Я очень новичок в разработке iOS, я начинаю использовать автоматическое расположение и ограничения.Я пришел из веб-дизайна, поэтому некоторые действия меня очень смущают.Я пытаюсь сделать вертикальное меню, принимая все страницы (по центру X и Y).Я сделал пользовательский класс только для этого меню.Цель состоит в том, чтобы легко создать любое меню, когда оно мне нужно, просто так:
myMenu = MyMenu([
MyMenu.ButtonInfo("Galerie","icon_gallery",onclick:{return}),
MyMenu.ButtonInfo("Camera","icon_camera",onclick:{return})
]);
myMenu.show()
Этот код создаст и отобразит большое меню, занимающее все окна (с черным макетом с непрозрачностью 0,5 позади него).Вот что я хочу создать:
Иллюстрация меню (изображение):
![Illustration of the menu (image)](https://i.stack.imgur.com/faNsX.png)
Я хочу создать все программно.Поэтому я сначала создал вертикальный UIStackView и добавляю в него пользовательские UIViews (пользовательский класс, который я называю «кнопка меню». Каждый «MenuButtom» - это значок слева и метка справа. Вот код кодаПользовательское представление MenuButton
class MenuButton: UIView {
var labelView = UILabel()
var iconView:UIImageView
public var title:String
public var icon:String
public var callback: ()->Void
init(_ title:String, _ icon:String,_ callback:@escaping ()->Void )
{
self.title = title
self.icon = icon
self.callback = callback
self.iconView = UIImageView(image:UIImage(named: icon)!)
super.init(frame: CGRect.zero)
self.frame = CGRect.zero
self.translatesAutoresizingMaskIntoConstraints = false
self.layoutIfNeeded()
self.addSubview(iconView)
self.addSubview(labelView)
iconView.translatesAutoresizingMaskIntoConstraints = false
labelView.translatesAutoresizingMaskIntoConstraints = false
labelView.backgroundColor = UIColor.green
iconView.trailingAnchor.constraint(equalTo: labelView.leadingAnchor).isActive = true
labelView.text = title
labelView.textColor = UIColor.white
self.backgroundColor = UIColor.purple
// self.heightAnchor.constraint(equalToConstant:50.0).isActive = true
// self.widthAnchor.constraint(equalToConstant:50.0).isActive = true
self.layer.borderWidth = 1
self.layer.borderColor = UIColor.red.cgColor
// this changes nothing so i commented it ..
//self.sizeToFit()
}
required init(coder aDecoder: NSCoder) {
fatalError("This class does not support NSCoding")
}
}
Вот код, который создает представление стека и добавляет в него кнопки MenuButtons:
func show()
{
win.addSubview(modalView)
// code for the 0.5-opacity dark layout behind the menu : this works well
modalView.addGestureRecognizer(UITapGestureRecognizer(
target:self,action : #selector(dismiss)
))
self.modalView.alpha = 0
UIView.animate(withDuration:0.2){
self.modalView.alpha = 1
}
// i create the vertical stackview :
let parentButtons = UIStackView()
parentButtons.translatesAutoresizingMaskIntoConstraints = false
parentButtons.distribution = .fillEqually
parentButtons.axis = .vertical
parentButtons.alignment = .fill
parentButtons.sizeToFit() // ***2*** doesnt work ...
parentButtons.layoutIfNeeded() // ***3*** do we need to call this only once after creating the view or everytime we need it to update?
win.addSubview(parentButtons)
// center my uistackview in the middle of the screen
parentButtons.centerYAnchor.constraint(equalTo: win.centerYAnchor).isActive = true
parentButtons.centerXAnchor.constraint(equalTo: win.centerXAnchor).isActive = true
var btn1 = MenuButton("camera", "icon_camera",{ return })
var btn2 = MenuButton("gallery", "icon_gallery",{ return })
parentButtons.addArrangedSubview(btn1)
parentButtons.addArrangedSubview(btn2)
}
И вот результат, совсем не тот, который я ожидал ...: Результат 1:
![Result 1](https://i.stack.imgur.com/IUiJd.png)
Я понял, что две кнопки MenuButton фактически перекрываются (я не понимаю, почему). Затем, логически, я хотел сделатьразмеры MenuButton, такие как он, могут обернуть по крайней мере все дочерние элементы, которые он содержит. Я нахожу «волшебный» метод в документации: .sizeToFit (). Но ничего не происходит, когда я раскомментирую self.sizeToFit в классе MenuButton. Нет фиолетовогофон и отсутствие красной рамки (стиль MenuButton) Итак, мой первый вопрос: я не понимаю, почему содержимое кнопки меню не расходуется, чтобы соответствовать максимуму между меткой изначок, который он содержит, когда я вызываю self.sizeToFit ().То, что я хочу, так же, как два ребенка "div" в большом родительском div (эквивалент в сети);здесь родительский размер автоматически изменит размер, чтобы соответствовать точно его дочерним элементам:
<div class="menuButtonEquivalent">
<div class="icon" style="float:left"><img ... /></div>
<div class="label"> label ... </div>
</div>
Затем я все равно хотел попытаться исправить проблему, установив ограничение на MenuButton: я раскомментирую ограничения на ширину и высотув классе MenuButton.Вот результат:
Результат с ограничениями на ButtonMenu:
![Result with the constraints on ButtonMenu](https://i.stack.imgur.com/wBHuO.png)
Так что это немного лучше, но у меня есть вопрос: почемумой MenuButton X начинается с метки, а не с иконки.Почему это не охватывает всех детей в этом?Почему только метка, а не только значок или и то, и другое (то, что я хочу).
У меня есть еще один третий вопрос, всегда ли необходимо писать подробное ".translatesAutoresizingMaskIntoConstraints = false
" каждый раз, когда создается ребенок,использовать autolayout?
Я пытаюсь все делать программно, а не с помощью nib-редактора (я хочу точно знать, как все работает, прежде чем использовать какой-либо инструмент более высокого уровня).