Проблема при настройке углового радиуса просмотра внутри ячейки?

У меня есть пользовательская ячейка UITableView. Я устанавливаю ее нижний левый и нижний правый радиус. Я устанавливаю радиус угла в cellForAtindexPath.Below - это код для этого

  if indexPath.row == 9 {

    recipeInfoCell.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 10)
    recipeInfoCell.layoutSubviews()
    recipeInfoCell.layoutIfNeeded()
  }
  else  {

    recipeInfoCell.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 0)
    recipeInfoCell.layoutSubviews()


  }

Теперь, когда я впервые запускаю tableview, он не устанавливает радиус угла. Но когда я снова прокручиваю, он устанавливает радиус угла.

Я создал расширение UIView, в котором есть одна функция, которая устанавливает радиус угла

  func roundCorners(corners:UIRectCorner, radius: CGFloat) {

    let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
    let mask = CAShapeLayer()
    mask.path = path.cgPath
    self.layer.mask = mask
  }

Расскажите, как я могу это решить?

Ответ 1

Я не думаю, что это хорошая идея установить угол радиуса в cellForRow atIndexPath. Причина в том, что эта функция вызывается много раз за время жизни UITableView, и вам нужно только установить радиус угла только один раз, и это тоже, когда ячейка инициализирована. Изменение радиуса углов на основе indexPath также повлияет на производительность UITableView.

Лучшим способом для этого было бы создать две ячейки: одну с угловым радиусом как 0, а другую с 10 и использование этих ячеек на основе indexPath.

Затем вы можете поместить свою логику setRadius в функцию layoutSubview в свою пользовательскую ячейку.

Если вы хотите сделать это только в методах tableView, правильный способ - сделать это в willDisplayCell, потому что после этого вызова функция layoutSubviews ячейки в вызываемом.

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        if indexPath.row % 2 == 0 {
            let path = UIBezierPath(roundedRect: cell.contentView.bounds, byRoundingCorners: [.bottomRight, .bottomLeft], cornerRadii: CGSize(width: 10, height: 10))
            let mask = CAShapeLayer()
            mask.path = path.cgPath
            cell.contentView.layer.mask = mask
        } else {
            let path = UIBezierPath(roundedRect: cell.bounds, byRoundingCorners: [.bottomRight, .bottomLeft], cornerRadii: CGSize(width: 0, height: 0))
            let mask = CAShapeLayer()
            mask.path = path.cgPath
            cell.contentView.layer.mask = mask
        }
    }

ОБНОВЛЕНИЕ: 19 мая 2017 г.

Вышеупомянутая концепция будет работать отлично, когда представление, которое вы хотите округлить и помещать в тень, имеет тот же размер, что и представление содержимого ячейки. Но если это что-то другое, это не сработает.

Причиной приведенного выше утверждения является то, что в момент вызова willDisplayCell, где приведенный выше код использует cell.contentView.bounds, другие представления еще не вычислены. Поэтому, когда мы будем использовать другое представление, нам нужно будет использовать эту оценку для вычисления кадра маски, который мы будем отличать от фактического.

Прочитав это немного, я узнал, что для этого нужно переопределить функцию draw(_ rect: CGRect) UITableViewCell. Поскольку на данный момент размер представления был правильно рассчитан, и мы можем создать правильный фрейм.

Ниже приведен код из пользовательского класса UITableViewCell:

override func draw(_ rect: CGRect) {
        let path = UIBezierPath(roundedRect: self.outerView.bounds, byRoundingCorners: [.bottomRight, .bottomLeft], cornerRadii: CGSize(width: 10, height: 10))
        let mask = CAShapeLayer()
        mask.path = path.cgPath
        self.outerView.layer.mask = mask

        let shadowLayer = CAShapeLayer()
        shadowLayer.shadowPath = path.cgPath
        shadowLayer.frame = self.outerView.layer.frame
        print(shadowLayer.frame)
        shadowLayer.shadowOffset = CGSize(width: 0, height: 0)
        shadowLayer.shadowColor = UIColor.black.cgColor
        shadowLayer.shadowOpacity = 0.9
        self.contentView.layer.insertSublayer(shadowLayer, below: self.outerView.layer)
        super.draw(rect)
    }

Ответ 2

Попробуйте написать эти строки кода в layoutSubviews() вашего пользовательского UITableViewCell

override func layoutSubviews() {
super.layoutSubviews()
self.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 10)
}

Ответ 3

введите круговой код в основной очереди следующим образом:

if indexPath.row == 9 { dispatch_async(dispatch_get_main_queue(),{
recipeInfoCell.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 10)
   })} else{
 dispatch_async(dispatch_get_main_queue(),{
recipeInfoCell.outerView.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 0)
}) }

Ответ 4

Для получения этого в swift только я использую для создания одного подкласса UIButton, как показано ниже

(в любом .swift файле проекта)

//MARK: Custom Class for UIView
open class CustomView: UIView {
    open func drawViewsForRect(_ rect: CGRect) {
        fatalError("\(#function) must be overridden")
    }

    open func updateViewsForBoundsChange(_ bounds: CGRect) {
        fatalError("\(#function) must be overridden")
    }

}

Затем определите нижеприведенные методы в том же или отложенном файле .swift, как этот

    //MARK: - UIView Property Class
@IBDesignable open class CView : CustomView{

    @IBInspectable dynamic open var borderColor: UIColor = UIColor.clear{
        didSet{
            updateBorderColor()
        }
    }

    @IBInspectable dynamic open var borderWidth: CGFloat = 1.0{
        didSet{
            updateBorderWidth()
        }
    }

    @IBInspectable dynamic open var cornerRadius: CGFloat = 0.0{
        didSet{
            updateBorderRadius()
        }
    }

    @IBInspectable dynamic open var shadowColor: UIColor?{
        didSet{
            updateShadowColor()
        }
    }

    @IBInspectable dynamic open var shadowRadius: CGFloat = 0.0{
        didSet{
            updateShadowRadius()
        }
    }

    @IBInspectable dynamic open var shadowOpacity: Float = 0.0{
        didSet{
            updateShadowOpacity()
        }
    }

    @IBInspectable dynamic open var shadowOffSet: CGSize = CGSize(width: 0.0, height: 0.0){
        didSet{
            updateShadowOffset()
        }
    }

    //Update Borders Properties
    open func updateBorderColor(){
        self.layer.borderColor = borderColor.cgColor
    }
    open func updateBorderRadius(){
        self.layer.cornerRadius = cornerRadius
    }
    open func updateBorderWidth(){
        self.layer.borderWidth = borderWidth
    }

    //Update Shadow Properties
    open func updateShadowColor(){
        self.layer.shadowColor = shadowColor?.cgColor
        self.clipsToBounds = false;
        self.layer.masksToBounds = false;
    }
    open func updateShadowOpacity(){
        self.layer.shadowOpacity = shadowOpacity
        self.clipsToBounds = false;
        self.layer.masksToBounds = false;
    }
    open func updateShadowRadius(){
        self.layer.shadowRadius = shadowRadius
        self.clipsToBounds = false;
        self.layer.masksToBounds = false;
    }
    open func updateShadowOffset(){
        self.layer.shadowOffset = CGSize(width: shadowOffSet.width, height: shadowOffSet.height)
        self.layer.shadowColor = shadowColor?.cgColor
        self.clipsToBounds = false;
        self.layer.masksToBounds = false;
    }
}

Затем просто назначьте класс CView в раскадровке во время разработки для любого контроллера вида и просто укажите требуемые значения для свойств, которые находятся рядом с инспектором атрибутов для этого представления

В раскадровке

1) Класс вида Как этот

установить вызовы просмотра

2) Задайте свойство, подобное этому

Свойство как это

3) Это покажет вид сбоку дизайна, подобного этому

просмотр в раскадровке

С этим вы даже смогли увидеть радиус тени или угла прямо в своем конструкторе, т.е. в стороне от раскадровки, как третье изображение.

Ответ 5

Вы хотите, чтобы определенная ячейка была округлена, если я правильно понимаю. вот мое решение. Хотя я немного опаздываю, но я стараюсь помогать другим.:) Я просто добавил свое решение как изображение.

Шаг 1:

Создал пользовательскую ячейку и сделал необходимые шаги.

введите описание изображения здесь введите описание изображения здесь

Ниже приведен код для закругленного нижнего левого и нижнего правого. Прошу прощения за плохой стиль кодирования:

введите описание изображения здесь

Ниже приведена конфигурация контроллера My view для отображения tableView с закругленными ячейками.

введите описание изображения здесь

введите описание изображения здесь

И ниже момент истины:

введите описание изображения здесь