重用UIView会导致应用冻结

时间:2016-02-09 16:10:32

标签: ios swift uiview

我不确定这是一个错误还是我实际上做错了什么。

    let spacerView = UIView(frame: CGRectMake(0,0,10,10))

    self.drugNameTextField.leftViewMode = .Always
    self.drugNameTextField.leftView = spacerView

    self.locationTextField.leftViewMode = .Always
    self.locationTextField.leftView = spacerView

在此重用spacerview会导致我的应用永远无法通过启动画面。只是冻结。

如果我这样做,应用程序启动正常并使其超过启动屏幕:

    let spacerView = UIView(frame: CGRectMake(0,0,10,10))

    self.drugNameTextField.leftViewMode = .Always
    self.drugNameTextField.leftView = spacerView

    self.locationTextField.leftViewMode = .Always
    //self.locationTextField.leftView = spacerView

重复使用UIView这样的技术错误吗?或者我应该提交错误?

为了彻底起见,我知道你可以这样做:

    self.drugNameTextField.leftViewMode = .Always
    self.drugNameTextField.leftView     = UIView(frame: CGRectMake(0,0,10,10))

    self.locationTextField.leftViewMode = .Always
    self.locationTextField.leftView     = UIView(frame: CGRectMake(0,0,10,10))

1 个答案:

答案 0 :(得分:2)

不,你不能在两个地方使用相同的视图。

视图只能有一个超级视图。在布局过程中,drugNameTextField将其leftViewspacerView)添加为自身的子视图。然后locationTextField将其leftView添加为自身的子视图。由于这也是spacerViewspacerView首先将其自身从其父级中删除。

如果您在调试器中暂停,您将看到类似于此的堆栈跟踪:

#0  0x036bf6f1 in -[NSConcreteTextStorage string] ()
#1  0x0195b09f in -[UITextField _text] ()
#2  0x0195b55b in -[UITextField _hasContent] ()
#3  0x019580de in -[UITextField _layoutLabels] ()
#4  0x01958ccf in -[UITextField _layoutContent] ()
#5  0x01958e5e in -[UITextField layoutSubviews] ()
#6  0x00eeb1c2 in -[UIView(CALayerDelegate) layoutSublayersOfLayer:] ()
#7  0x00556059 in -[NSObject performSelector:withObject:] ()
#8  0x04e4392a in -[CALayer layoutSublayers] ()
#9  0x04e37194 in CA::Layer::layout_if_needed(CA::Transaction*) ()
#10 0x04e36ff8 in CA::Layer::layout_and_display_if_needed(CA::Transaction*) ()
#11 0x04e297b7 in CA::Context::commit_transaction(CA::Transaction*) ()
#12 0x04e5e107 in CA::Transaction::commit() ()
#13 0x04e5e9c8 in CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) ()
#14 0x0099b86e in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ ()
#15 0x0099b7ce in __CFRunLoopDoObservers ()
#16 0x00990978 in CFRunLoopRunSpecific ()
#17 0x0099076b in CFRunLoopRunInMode ()
#18 0x00e18812 in -[UIApplication _run] ()
#19 0x00e1e299 in UIApplicationMain ()
#20 0x0006c8ea in main at /Users/mayoff/TestProjects/test/test/main.m:14
#21 0x03180a25 in start ()

如果在-[UITextField layoutSubviews]上放置断点,您将看到系统一遍又一遍地调用它。这两个文本字段正在“争夺”谁成为spacerView的超级视图。每当一个文本字段添加spacerView作为子视图时,它会从其他文本字段的子视图中删除spacerView,因此其他文本字段会被标记为需要再次布局。系统永远不会退出布局阶段。