Проблемы с ограничениями: sizeToFit не работает - PullRequest
0 голосов
/ 15 октября 2018

Я очень новичок в разработке 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)

Я хочу создать все программно.Поэтому я сначала создал вертикальный 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

Я понял, что две кнопки 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

Так что это немного лучше, но у меня есть вопрос: почемумой MenuButton X начинается с метки, а не с иконки.Почему это не охватывает всех детей в этом?Почему только метка, а не только значок или и то, и другое (то, что я хочу).

У меня есть еще один третий вопрос, всегда ли необходимо писать подробное ".translatesAutoresizingMaskIntoConstraints = false" каждый раз, когда создается ребенок,использовать autolayout?

Я пытаюсь все делать программно, а не с помощью nib-редактора (я хочу точно знать, как все работает, прежде чем использовать какой-либо инструмент более высокого уровня).

1 Ответ

0 голосов
/ 14 ноября 2018

ТЕОРИЯ ЗА ОГРАНИЧЕНИЕМ АВТОМАТИЧЕСКОГО РАЗМЕЩЕНИЯ

В соответствии с iOS, быстро (0,0), т. Е. X и y находятся в верхнем левом углу экрана.Сохраняя ограничения, вы должны быть осторожны, потому что каждый экран iphone имеет свои размеры.Чтобы удовлетворить эти потребности, прежде всего нам нужно знать размер экрана и на основании этого мы можем установить выравнивание.

Например:

x=50, y=50, width=z-(x+x) height=a-(y+y)

где a - высота экрана, а z - ширина экрана.

При практическом добавлении UIview, а затем установке ограничений, не забудьте добавить свои изображения или что-то еще и дать имдетские отношения.СЧАСТЛИВЫЕ КОДИРОВАНИЕ !!!!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...