Как использовать настраиваемый вид в Swift?

Я хочу добавить настраиваемое представление в TableViewHeader. Но когда я запускаю следующий код, он создает цикл, и приложение застревает при любом взаимодействии с пользователем.

import UIKit
class ExpandableView: UIView {

    @IBOutlet weak var userImgView: UIImageView!
    @IBOutlet weak var userNamelbl: UILabel!
    @IBOutlet weak var countLbl: UILabel!
    @IBOutlet weak var rightArrowImgView: UIImageView!
    var isExpanded = false
    var contentView: UIView!
    @IBOutlet weak var checkMarkView: UIImageView!

    // Only override draw() if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func draw(_ rect: CGRect) {
        // Drawing code
    }
    public override init(frame: CGRect) {
        super.init(frame: frame)
        setUpView()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setUpView()
    }

    private func setUpView() {
        let bundle = Bundle(for: type(of: self))
        let nib = UINib(nibName: "ExpandableView", bundle: bundle)
        self.contentView = nib.instantiate(withOwner: self, options: nil).first as? UIView
        addSubview(contentView)
        contentView.center = self.center
        contentView.autoresizingMask = []
        contentView.translatesAutoresizingMaskIntoConstraints = true
    }
}

Я использую его следующим образом:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let frame = CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 60)
    let expandabelView = ExpandableView(frame: frame)
    return expandabelView
}

И он показывает следующую ошибку при запуске.

Как использовать настраиваемый вид в Swift?

По-прежнему не работает та же проблема

Inderjeet Singh 14.01.2019 12:28
init(coder:) вызовет setupView(), который вызывает UINib(nibName:bundle:), поэтому он снова вызовет init(coder:). Так почему вы вызываете UINib(nibName:bundle:) в initWithCoder?
Larme 14.01.2019 12:29
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
148
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Когда вы создаете собственный UIView, он должен следовать этому, если вы хотите использовать его init с фреймом.

class CustomView: UIView {
    //This should be contentview of your xib
    @IBOutlet var view: UIView!

    let nibName = "CustomView"

    override init(frame: CGRect) {
        super.init(frame: frame)
        xibSetup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        xibSetup()
    }

    private func xibSetup()
    {
        Bundle.main.loadNibNamed(nibName, owner: self, options: nil)
        self.view.autoresizesSubviews = true
        self.translatesAutoresizingMaskIntoConstraints = false

        self.addSubview(self.view)
        self.view.frame = self.frame


    }

}

Поскольку вам нужно представление нагрузка из перо, просто загрузите его, а затем добавьте подвид к вашему представлению. Затем установите frame представления содержимого и правильно установите маску автоматического изменения размера представления содержимого.

private func setUpView() {
    Bundle.main.loadNibNamed("ExpandableView", owner: self, options: nil)
    addSubview(contentView)
    contentView.frame = bounds
    contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
}
Ответ принят как подходящий

Может быть много других способов, но я рекомендую вам сделать ваш ExpandableView многоразовым, чтобы улучшить производительность.


Прежде всего, упростите свой класс ExpandableView:

import UIKit

class ExpandableView: UITableViewHeaderFooterView {
    @IBOutlet weak var userImgView: UIImageView!
    @IBOutlet weak var userNamelbl: UILabel!
    @IBOutlet weak var countLbl: UILabel!
    @IBOutlet weak var rightArrowImgView: UIImageView!
    var isExpanded = false

    @IBOutlet weak var checkMarkView: UIImageView!
}

Не упускайте, пожалуйста, суперкласс UITableViewHeaderFooterView, а не UIView.

Второй, проверьте настройки вашего ExpandableView.xib:

Параметр Пользовательский вид определенного представления должен быть ExpandableView.

Custom View of the view

Если вы не можете выбрать ExpandableView из раскрывающегося списка, вам может потребоваться ввести вручную. Не забудьте проверить Наследовать модуль от цели.

Параметр Custom View для Владелец файла должен быть пустым.

File's Owner

Если какой-то класс уже установлен, удалите его вручную.

Убедитесь, что все Торговые точки правильно подключены к вашему ExpandableView.

Outlets

(Вам лучше повторно подключить их все после того, как вы изменили свой xib.)

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

Третий, измените свой контроллер представления, содержащий табличное представление.

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        tableView.delegate = self
        tableView.dataSource = self
        //...
        let nib = UINib(nibName: "ExpandableView", bundle: nil)
        tableView.register(nib, forHeaderFooterViewReuseIdentifier: "ExpandableView")
        tableView.estimatedSectionHeaderHeight = 60
        tableView.sectionHeaderHeight = UITableView.automaticDimension
    }

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let expandabelView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "ExpandableView")
        // Frame size should be represented with constraints.
        return expandabelView
    }

Отличное объяснение. Спасибо.

Inderjeet Singh 16.01.2019 06:08

Другие вопросы по теме