Ответ 1
Вы пробовали это, назвав супер после ваших изменений?
override func viewWillAppear() {
self.nameLabel.text = "John"
self.summaryStackView.hidden = true
self.combinedStackView.hidden = true
super.viewWillAppear()
}
В моем приложении есть 2 экрана:
TableViewVC (здесь нет представлений стека)
DetailVC (все вложенные представления стека здесь, см. ссылку на картинку: Изображение вложенных стоп-кадров). Обратите внимание: есть ярлыки и изображения в этих представлениях стека.
Когда вы нажимаете ячейку в представлении таблицы, она передает информацию из TableViewVC в DetailVC. Проблема заключается в том, что скрывает определенные UIStackViews в DetailVC. Я хочу, чтобы только 2 представления стека из разных в DetailVC были скрыты, как только загрузится представление. Поэтому я пишу этот код в DetailVC, чтобы выполнить это:
override func viewDidLoad() {
super.viewDidLoad()
self.nameLabel.text = "John"
self.summaryStackView.hidden = true
self.combinedStackView.hidden = true
}
Все выглядит великолепно, но Xcode дает много предупреждений только в время исполнения. Когда приложение не работает, никаких предупреждений в раскадровке нет. См. Ссылку на изображение ошибок: Изображение ошибок
В основном это много UISV-скрытия, UISV-интервал, ошибки UISV-canvas-connection. Эти ошибки исчезают, если я скрываю те же представления стека в viewDidAppear
, но затем появляется флеш материала, который должен был быть скрыт, а затем он скрывается. Пользователь видит краткий обзор, а затем скрывает, что не очень хорошо.
Извините за то, что вы не можете отправлять фотографии, а не ссылки, но не можете этого сделать.
Любые предложения по устранению этого? Это приложение, которое я действительно хочу запустить в магазин приложений - это мое первое, поэтому любая помощь будет замечательной!
Изменить/Обновить 1:
Я нашел небольшую работу с этим кодом, который я разместил во втором экране с именем DetailVC:
// Function I use to delay hiding of views
func delay(delay: Double, closure: ()->()) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
// Hide the 2 stack views after 0.0001 seconds of screen loading
override func awakeFromNib() {
delay(0.001) { () -> () in
self.summaryStackView.hidden = true
self.combinedStackView.hidden = true
}
}
// Update view screen elements after 0.1 seconds in viewWillAppear
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
delay(0.1) { () -> () in
self.nameLabel.text = "John"
}
}
Это полностью избавляет от предупреждений о ограничениях макета из Xcode.
Это все еще не идеально, потому что иногда я вижу проблеск представлений, которые должны быть скрыты - они мгновенно вспыхивают на экране, а затем исчезают. Это происходит так быстро, хотя.
Любые предложения относительно того, почему это избавляет от предупреждений? Кроме того, любые предложения о том, как улучшить это, чтобы работать отлично??? Спасибо!
Вы пробовали это, назвав супер после ваших изменений?
override func viewWillAppear() {
self.nameLabel.text = "John"
self.summaryStackView.hidden = true
self.combinedStackView.hidden = true
super.viewWillAppear()
}
У меня была та же проблема, и я исправил ее, указав ограничения высоты моих изначально скрытых просмотров на приоритет 999.
Проблема заключается в том, что ваш стековый режим применяет ограничение высоты 0 на вашем скрытом виде, которое конфликтует с вашим другим ограничением по высоте. Это сообщение об ошибке:
Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x7fa3a5004310 V:[App.DummyView:0x7fa3a5003fd0(40)]>",
"<NSLayoutConstraint:0x7fa3a3e44190 'UISV-hiding' V:[App.DummyView:0x7fa3a5003fd0(0)]>"
)
Предоставляя ограничение по высоте, более низкий приоритет решает эту проблему.
Это известная проблема с скрытием вложенных представлений стека.
Существуют 3 решения этой проблемы:
innerStackView.removeFromSuperview()
, но тогда вам нужно будет запомнить, куда вставить представление стека.Третий вариант - лучший, на мой взгляд. Для получения дополнительной информации об этой проблеме, о том, почему это происходит, о различных решениях и о том, как реализовать решение 3, см. мой ответ на аналогичный вопрос.
Вы можете использовать свойство removeArrangedSubview и removeFromSuperview для UIStackView.
В Objective-C:
[self.topStackView removeArrangedSubview:self.summaryStackView];
[self.summaryStackView removeFromSuperview];
[self.topStackView removeArrangedSubview:self.combinedStackView];
[self.combinedStackView removeFromSuperview];
Из Apple UIStackView Документация:(https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIStackView_Class_Reference/#//apple_ref/occ/instm/UIStackView/removeArrangedSubview:)
Просмотр стека автоматически обновляет его расположение всякий раз, когда представления добавляются, удаляются или вставляются в массив builtSubviews.
Чтобы запретить появление представления на экране после вызова стеков removeArrangedSubview: метод, явным образом удалить представление из массива subviews, вызвав метод removeFromSuperview, или установить для скрытого свойства views значение YES.
Когда UIViewStack скрыт, ограничения, автоматически генерируемые UIStackView, будут вызывать множество UISV-скрывающих, UISV-интервалов, предупреждений UISV-canvas-connection, если свойство интервала UIStackView имеет любое значение, отличное от нуля.
Это не имеет большого смысла, это почти наверняка ошибка структуры. Обходной путь, который я использую, заключается в том, чтобы установить расстояние до нуля при скрытии компонента.
if hideStackView {
myStackView.hidden = true
myStackView.spacing = CGFloat(0)
} else {
myStackView.hidden = false
myStackView.spacing = CGFloat(8)
}
Я переместил весь код UIStackView.hidden из viewDidLoad в viewDidAppear и проблема с ограниченными ограничениями исчезла. В моем случае все конфликтующие ограничения были сгенерированы автоматически, поэтому не удалось настроить приоритеты.
Я также использовал этот код, чтобы сделать его более красивым:
UIView.animateWithDuration(0.5) {
self.deliveryGroup.hidden = self.shipVia != "1"
}
EDIT:
Также необходим следующий код, чтобы остановить его при повторном запуске устройства:
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
self.deliveryGroup.hidden = false
coordinator.animateAlongsideTransition(nil) {
context in
self.deliveryGroup.hidden = self.shipVia != "1"
}
}
Я исправил это, поместив команды hide в traitCollectionDidChange.
override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
self.item.hidden = true
}
Я обнаружил, что вложенные UIStackViews показывают это поведение, если вы задали скрытое свойство в ✨Interface Builder✨. Мое решение состояло в том, чтобы все было не скрыто в "Внутреннем Builder" и выборочно скрывать вещи в viewWillAppear.
Эта ошибка не о скрытии, а о неоднозначных ограничениях. У вас не должно быть никаких двусмысленных ограничений. Если вы добавите их программно, вы должны точно понять, какие ограничения вы добавляете и как они работают вместе. Если вы не добавляете их программно, но используйте раскадровку или xib, что является хорошим местом для начала, убедитесь, что нет ограничений или предупреждений об ограничениях.
UPD: у вас довольно сложная структура просмотров. Не видя ограничений, трудно сказать, что именно не так. Тем не менее, я бы предложил построить иерархию представлений, постепенно добавляя представления один за другим и следя за тем, чтобы не было предупреждений о времени разработки/времени выполнения. Прокрутка может добавить еще один уровень сложности, если вы не справитесь с этим правильно. Узнайте, как использовать ограничения со списком прокрутки. Все остальные временные хаки не являются решением в любом случае.
Поместите свои команды hide в viewWillLayoutSubviews() {}