Я хочу добавить настраиваемое представление в 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
}
И он показывает следующую ошибку при запуске.

init(coder:) вызовет setupView(), который вызывает UINib(nibName:bundle:), поэтому он снова вызовет init(coder:). Так почему вы вызываете UINib(nibName:bundle:) в initWithCoder?





Когда вы создаете собственный 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.
Если вы не можете выбрать ExpandableView из раскрывающегося списка, вам может потребоваться ввести вручную. Не забудьте проверить Наследовать модуль от цели.
Параметр Custom View для Владелец файла должен быть пустым.
Если какой-то класс уже установлен, удалите его вручную.
Убедитесь, что все Торговые точки правильно подключены к вашему ExpandableView.
(Вам лучше повторно подключить их все после того, как вы изменили свой 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
}
Отличное объяснение. Спасибо.
По-прежнему не работает та же проблема