Reputation: 8608
I'm not sure if this is a bug or if I'm actually doing something wrong.
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
Reusing spacerview
here causes my app to never get past the splash screen. Simply freezes.
If I do this, app launches fine and makes it past the splash screen:
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
Is reusing a UIView
like this technically wrong? Or should I file a bug?
Just for thoroughness sake, I know you could do this:
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))
Upvotes: 0
Views: 241
Reputation: 385690
No, you can't use the same view in two places like that.
A view can have only one superview. During layout, drugNameTextField
adds its leftView
(spacerView
) as a subview of itself. Then locationTextField
adds its leftView
as a subview of itself. Since that is also spacerView
, spacerView
first removes itself from its parent.
If you pause in the debugger, you'll see a stack trace similar to this:
#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 ()
If you put a breakpoint on -[UITextField layoutSubviews]
, you'll see that the system is calling it over and over. The two text fields are “fighting” over who gets to be the superview of spacerView
. Each time one text field adds spacerView
as a subview, it removes spacerView
from the other text field's subviews, so the other text field gets flagged as needing layout again. The system never gets out of the layout phase.
Upvotes: 2