UIStackView - 隐藏堆栈视图时的布局约束问题

JEL*_*JEL 22 ios swift uistackview

我的应用有2个屏幕:

  1. TableViewVC(这里没有堆栈视图)

  2. DetailVC(此处所有嵌套堆栈视图;请参见图片链接:嵌套StackViews图片) - 注意,这些堆栈视图中有标签和图像.

当您按下tableview中的单元格时,它会将信息从TableViewVC传递到DetailVC.问题是隐藏DetailVC中的特定UIStackViews.我只想在视图加载时隐藏DetailVC中各个窗口中的2个堆栈视图.所以我在DetailVC中编写这段代码来完成这个:

override func viewDidLoad() {
    super.viewDidLoad()

    self.nameLabel.text = "John"

    self.summaryStackView.hidden = true
    self.combinedStackView.hidden = true
}
Run Code Online (Sandbox Code Playgroud)

一切看起来都很棒,但Xcode只在运行时发出许多警告.应用程序未运行时,Storyboard中没有警告.请参阅错误图片的链接:错误图片

基本上它是很多UISV隐藏,UISV间距,UISV-canvas连接错误.如果我隐藏相同的堆栈视图,这些错误就会消失,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"
    }
}
Run Code Online (Sandbox Code Playgroud)

这完全消除了Xcode中关于布局约束的警告.

它仍然不完美,因为有时候我会看到一些应该被隐藏的视图 - 它们在屏幕上快速闪烁然后消失.这种情况发生得如此之快.

有关为什么要摆脱警告的任何建议?此外,任何关于如何改善这种工作完美工作的建议??? 谢谢!

Rap*_*ael 83

我有同样的问题,我通过给出我最初隐藏的视图的高度限制优先级为999来修复它.

在此输入图像描述

问题是您的stackview在隐藏视图上应用了高度约束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)]>"
)
Run Code Online (Sandbox Code Playgroud)

将高度限制设置为较低优先级可解决此问题.

  • 唯一的问题是当您的堆栈视图中有非零间距时。间距约束仍然与隐藏约束冲突。 (2认同)

Sen*_*ful 26

这是隐藏嵌套堆栈视图的已知问题.

这个问题基本上有3个解决方案:

  1. 将间距更改为0,但是您需要记住之前的间距值.
  2. 调用innerStackView.removeFromSuperview(),但是你需要记住插入堆栈视图的位置.
  3. 在具有至少一个999约束的UIView中包装堆栈视图.例如Top,Leading,Trailing @ 1000,Bottom @ 999.

在我看来,第三种选择是最好的.有关此问题的更多信息,为什么会发生,不同的解决方案以及如何实现解决方案3,请参阅我对类似问题的回答.

  • 第三个选项效果很好,并提供了一个非常干净的解决方案。谢谢你的分享! (3认同)

Din*_*esh 8

您可以使用UIStackView的removeArrangedSubview和removeFromSuperview属性.

在Objective-C中:

 [self.topStackView removeArrangedSubview:self.summaryStackView];
 [self.summaryStackView removeFromSuperview];

 [self.topStackView removeArrangedSubview:self.combinedStackView];
 [self.combinedStackView removeFromSuperview];
Run Code Online (Sandbox Code Playgroud)

从Apple UIStackView文档:( https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIStackView_Class_Reference/#//apple_ref/occ/instm/UIStackView/removeArrangedSubview :)

每当添加,删除或插入到excludedSubviews数组中的视图时,堆栈视图都会自动更新其布局.

  • removeArrangedSubview:此方法从堆栈的arrangeSubviews数组中删除提供的视图.视图的位置和大小将不再由堆栈视图管理.但是,此方法不会从堆栈的子视图数组中删除提供的视图; 因此,视图仍显示为视图层次结构的一部分.

要在调用堆栈的removeArrangedSubview:方法后阻止视图出现在屏幕上,请通过调用视图的removeFromSuperview方法从子视图数组中显式删除视图,或将视图的hidden属性设置为YES.


ada*_*mek -4

你试过这个吗?super更改后打电话?

override func viewWillAppear() {
    self.nameLabel.text = "John"
    self.summaryStackView.hidden = true
    self.combinedStackView.hidden = true
    super.viewWillAppear()
}
Run Code Online (Sandbox Code Playgroud)