AutoLayout изменяет размер пользовательского содержимого UIView

У меня есть стандартный UIView, добавленный через IB, который меняет размер в зависимости от ориентации с использованием ограничений. Программно я добавляю к этому представлению пользовательский компонент (подкласс UIView), который по умолчанию имеет размер sam в качестве его родительского представления. Проблема в том, как мне заставить свой пользовательский вид (добавленный программно) обновлять свой размер в соответствии с его родителем при изменении размера родителей (из-за изменения ориентации)?

@IBOutlet weak var cardView: UIView!
override func viewDidLoad() {
    super.viewDidLoad()

    let frame = cardView.bounds
    // Custom component sub classes UI View
    // Should always be same size as its parent
    let imageTemplateView: ImageTemplateView = ImageTemplateView(frame: frame)

    cardView.addSubview(imageTemplateView)
}

person MikeJ    schedule 23.08.2016    source источник
comment
попробуйте использовать clipsToBounds   -  person Gokul G    schedule 23.08.2016


Ответы (4)


А вот и viewDidLayoutSubviews, чтобы решить нашу проблему,

Описание:

Когда границы представления контроллера представления изменяются, представление корректирует позиции своих подпредставлений, а затем система вызывает этот метод.

Вместо viewDidLoad используйте viewDidLayoutSubviews следующим образом

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    let imageTemplateView: ImageTemplateView = ImageTemplateView(frame: frame)
    cardView.addSubview(imageTemplateView)
    imageTemplateView.clipsToBounds = true
}

ОБНОВЛЕНИЕ:

  • Объявить переменную выше viewdidload

    var imageTemplateView: ImageTemplateView = ImageTemplateView()
    
  • установить фрейм и добавить его как дополнительный вид в viewdidload

    override func viewDidLoad() {
      imageTemplateView = ImageTemplateView(frame: frame)
      cardView.addSubview(imageTemplateView)
      imageTemplateView.clipsToBounds = true
    }
    
  • В viewDidLayoutSubviews просто установите рамку отдельно, чтобы при изменении ориентации ImageTemplateView рамка обновлялась.

    override func viewDidLayoutSubviews() {
      super.viewDidLayoutSubviews()
      imageTemplateView = ImageTemplateView(frame: frame)
    }
    
person Gokul G    schedule 23.08.2016
comment
он будет добавлять еще один imageTemplateView в качестве подвида, когда когда-либо вызывается viewDidLayoutSubviews - person Ravi; 23.08.2016
comment
Это неправильный подход. добавление любого объекта, такого как изображение или метка, или что-то еще в viewDidLayoutSubviews, является плохой идеей, потому что каждый раз он будет добавлять новый объект при вызове viewDidLayoutSubviews. Если ориентация вашего устройства изменится, то также будет вызван этот метод. Поэтому добавьте представление в viewdidload и измените его размер в viewDidLayoutSubviews в соответствии с необходимостью. - person Ketan Parmar; 23.08.2016
comment
Раки уже предлагал это.проверьте обновление..Только изменение рамки в viewDidLayoutSubviews - person Gokul G; 23.08.2016

Установите top,bottom,leading and trailing ограничения вашего программно добавленного представления с константой 0 каждого. Таким образом, он всегда будет иметь одинаковый размер по отношению к родительскому представлению, которое вы добавили в IB. Если вам нужен рациональный (например, половина высоты и ширины родительского представления или что-то еще) height или width, вы можете управлять им, играя с constant и multiplier.

Если вы не знаете, как программно добавлять ограничения, вы можете обратиться к Этот пост SO .

person Ketan Parmar    schedule 23.08.2016
comment
Я думаю, что использование viewDidLayoutSubviews в этом случае проще всего, но я вижу, как программная установка ограничений полезна для большей точности позиционирования. Большое спасибо. - person MikeJ; 23.08.2016
comment
пожалуйста..!!! добавление новых объектов в viewDidLayoutSubviews не является хорошим подходом. Вы должны добавить его из viewdidload, который вызывается только один раз. - person Ketan Parmar; 23.08.2016

попробуй это

@IBOutlet weak var cardView: UIView!
var imageTemplateView:ImageTemplateView!

override func viewDidLoad() 
{
    super.viewDidLoad()
    imageTemplateView = ImageTemplateView(frame: cardView.bounds)
    cardView.addSubview(imageTemplateView)
}

override func viewDidLayoutSubviews() 
{
    super.viewDidLayoutSubviews()
    imageTemplateView.frame = cardView.bounds
}
person Ravi    schedule 23.08.2016
comment
модифицированный метод viewDidLayoutSubviews - person Ravi; 23.08.2016