UIButton is nil in MFMessageComposeController on iOS 6.0 - iphone

I am trying to print the view hierarchy of the application's visible and hidden windows. Here is a part of my code inside a subclass of MFMessageComposeViewController:
NSArray *windows = [[UIApplication sharedApplication] windows];
for(UIWindow *aWindow in windows) {
if([aWindow isMemberOfClass:NSClassFromString(#"UITextEffectsWindow")]) {
sendButton = [self findButtonInView:aWindow];
break;
}
}
The findButtonInView: method is searching recursively a UIButton in the current UIWindow.
This is working as expected when testing with iOS4.3 and iOS 5.1 (the expected UIButton is found successfully), but does not work with iOS6.
Here are the results of the view hierarchy prints from both tests:
iOS 4.3:
<UITextEffectsWindow: 0x1e32a0; frame = (0 0; 320 480); opaque = NO; layer = <CALayer: 0x1e33d0>>
| <UIPeripheralHostView: 0x1e4a80; frame = (0 224; 320 256); autoresizesSubviews = NO; layer = <UIPeripheralHostLayer: 0x1e4e60>>
| | <UIKeyboardAutomatic: 0x1ad300; frame = (0 40; 320 216); opaque = NO; layer = <CALayer: 0x1ad3b0>>
| | | <UIKeyboardImpl: 0x1ad520; frame = (0 0; 320 216); opaque = NO; layer = <CALayer: 0x1ad6c0>>
| | | | <UIKeyboardLayoutStar: 0x1d47c0; frame = (0 0; 320 216); layer = <CALayer: 0x19ca40>>
| | | | | <UIKBKeyplaneView: 0x1df880; frame = (0 0; 320 216); layer = <CALayer: 0x1df900>>
| | | | | | <UIKBKeyView: 0x1dfe00; frame = (1 119; 40 42); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x1dffd0>>
| | | | | | <UIKBKeyView: 0x1e0090; frame = (279 119; 40 42); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x1e00e0>>
| | | | | | <UIKBKeyView: 0x1e01e0; frame = (1 173; 38 42); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x1e0230>>
| | | | | | <UIKBKeyView: 0x1dbfb0; frame = (41 173; 38 42); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x1dc050>>
| | | | | | <UIKBKeyView: 0x1e0330; frame = (81 173; 158 42); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x1e0380>>
| | | | | | <UIKBKeyView: 0x1e0440; frame = (241 173; 78 42); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x1e0490>>
| | <CKMessageEntryView: 0x182500; baseClass = UIImageView; frame = (0 0; 320 40); opaque = NO; autoresize = W+TM; layer = <CALayer: 0x1837c0>>
| | | <UIButton: 0x1878c0; frame = (6 8; 26 27); hidden = YES; opaque = NO; autoresize = RM+TM; layer = <CALayer: 0x182e60>>
| | | | <UIImageView: 0x1e56f0; frame = (0 0; 26 27); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x1e5720>>
| | | <UIView: 0x184dd0; frame = (7 0; 245 40); autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x185130>>
| | | <CKContentEntryView: 0x188a50; baseClass = UIScrollView; frame = (6 0; 249 40); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x187230>; contentOffset: {-0, -10}>
| | | | <CKRichContentView: 0x193790; baseClass = UITextContentView; frame = (0 0; 249 20); text = ''; autoresize = W; layer = <CALayer: 0x1938a0>>
| | | | | <UIWebDocumentView: 0xaef200; frame = (0 0; 249 20); text = '
'; opaque = NO; userInteractionEnabled = NO; layer = <UIWebLayer: 0x196c20>>
| | | | | <UITextSelectionView: 0x1a5b60; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <CALayer: 0x1a5c00>>
| | | | <UIImageView: 0x189fa0; frame = (242 10; 7 20); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x189ff0>>
| | | | <UIImageView: 0x189eb0; frame = (242 23; 7 7); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x189f00>>
| | | <UIImageView: 0x18a190; frame = (7 0; 245 40); opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x18a510>>
| | | <UILabel: 0x18a6b0; frame = (245 13; 73 15); text = 'TEST'; clipsToBounds = YES; hidden = YES; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x18a720>>
| | | <UIButton: 0x180d00; frame = (252 8; 61 27); opaque = NO; autoresize = LM+TM; layer = <CALayer: 0x184e00>>
| | | | <UIImageView: 0x1ad460; frame = (0 0; 61 27); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x1ad490>>
| | | | <UIButtonLabel: 0x1871c0; frame = (11 3; 39 20); text = 'Send'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x187280>>
iOS 6.0:
<UIWindow: 0x1fd81f80; frame = (0 0; 320 480); opaque = NO; autoresize = RM+BM; layer = <UIWindowLayer: 0x1fd82080>>
| <UILayoutContainerView: 0x1fd94d50; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0x1fd94df0>>
| | <UINavigationTransitionView: 0x1fd9a450; frame = (0 0; 320 480); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x1fd9a520>>
| | | <UIViewControllerWrapperView: 0x1fdac9a0; frame = (0 20; 320 460); autoresize = W+H; layer = <CALayer: 0x1fdaca30>>
| | | | <UIView: 0x1fda8cb0; frame = (0 0; 320 460); autoresize = W+H; layer = <CALayer: 0x1fda8c70>>
| | | | | <_UISizeTrackingView: 0x1fda6430; frame = (0 0; 320 460); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x1fda6510>>
| | | | | | <_UIRemoteView: 0x1fda6700; frame = (0 0; 320 480); transform = [0.5, -0, 0, 0.5, -0, 0]; userInteractionEnabled = NO; layer = <CALayerHost: 0x1fda6850>>
My question is how the needed UIButton can be found inside UITextEffectsWindow?
It seems that the view hierarchy in iOS6 is somehow changed...
I would appreciate any help. Thanks!

It is likely that is it changed. You are accessing undocumented elements presented in the UI, which is not guaranteed to be consistent across system updates. If you would like to change the appearance of the UI elements presented in the MFMailComposeViewController class, use the IUAppearance API. You are not supposed to access much of the mail controller class.
Important The mail composition interface itself is not customizable and must not be modified by your application. In addition, after presenting the interface, your application is not allowed to make further changes to the email content. The user may still edit the content using the interface, but programmatic changes are ignored. Thus, you must set the values of content fields before presenting the interface.

Related

Info windows in the ios7 iphone

In the ios7 many times when you click on the one of the button on the tab bar, a windows appear that contains some items with a done button on the right of the navigation bar. Below image show this windows on the map application of the ios7.
Is this a new component like action-sheet or just a custom view? I want to create a page like this, what is the best way?
Since the maps app is available in the simulator, you can attach to it using the debugger and sent messages to its objects.
Here is a print of the recursive description of the key window:
<UIWindow: 0x10ab27890; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x10ab280a0>; layer = <UIWindowLayer: 0x10ab26ba0>>
| <UILayoutContainerView: 0x10af73b20; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x10af7d1b0>; layer = <CALayer: 0x10af74420>>
| | <UINavigationTransitionView: 0x10af75700; frame = (0 0; 320 568); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x10af08c20>>
| | | <UIViewControllerWrapperView: 0x111aaea00; frame = (0 0; 320 568); layer = <CALayer: 0x10abb2990>>
| | | | <UIView: 0x10af7e3d0; frame = (0 0; 320 568); clipsToBounds = YES; layer = <CALayer: 0x10af7e690>>
| | | | | <UIView: 0x10af7e6b0; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 0x10ab47cb0>; layer = <CALayer: 0x10af7e770>>
| | | | | | <MKMapView: 0x10af7eca0; frame = (0 0; 320 568); clipsToBounds = YES; userInteractionEnabled = NO; gestureRecognizers = <NSArray: 0x10abfb9f0>; layer = <CALayer: 0x10af7e940>>
| | | | | | | <UIView: 0x10af809e0; frame = (0 0; 320 568); autoresizesSubviews = NO; gestureRecognizers = <NSArray: 0x10ab4a980>; layer = <CALayer: 0x10af80aa0>>
| | | | | | | | <MKBasicMapView: 0x10af80fb0; frame = (0 0; 320 568); clipsToBounds = YES; layer = <CALayer: 0x10af81150>>
| | | | | | | | | <_MKMapLayerHostingView: 0x10af81ca0; frame = (0 0; 320 568); layer = <_MKMapLayerHostingLayer: 0x10af81fd0>>
| | | | | | | | | | <VKMapView: 0x10af82a30> (layer)
| | | | | | | | | | | <VKMapCanvas: 0x10af9ca60> (layer)
| | | | | | | | | | | | <VGLLayer: 0x10c90ed40> (layer)
| | | | | | | | <MKScrollContainerView: 0x111ab4a30; frame = (-1.3491e+06 -3.25471e+06; 8.38861e+06 8.38861e+06); autoresizesSubviews = NO; layer = <CALayer: 0x10aba9420>>
| | | | | | | | <MKNewAnnotationContainerView: 0x111ab4ff0; frame = (0 0; 320 568); autoresize = W+H; autoresizesSubviews = NO; layer = <CALayer: 0x10ab7d3b0>>
| | | | | | | | | <UserLocationView: 0x10c981e70; frame = (138.651 271.783; 42 44); layer = <CALayer: 0x10c9f2a30>>
| | | | | | | | | | <CALayer: 0x10c97e250> (layer)
| | | | | | | | | | <CALayer: 0x10c981e00> (layer)
| | | | | | | | | | <CALayer: 0x10c9bfd60> (layer)
| | | | | | | | | | | <CALayer: 0x10c984cc0> (layer)
| | | | | | <BlurView: 0x111ab0cd0; frame = (0 0; 320 64); layer = <CALayer: 0x111ab0db0>>
| | | | | | | <_UIBackdropView: 0x111ab4c40; frame = (0 0; 320 64); opaque = NO; autoresize = W+H; layer = <_UIBackdropViewLayer: 0x10ab61940>>
| | | | | | | | <_UIBackdropEffectView: 0x10ab32bc0; frame = (0 0; 320 64); clipsToBounds = YES; opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <CABackdropLayer: 0x111a07ee0>>
| | | | | | | | <UIView: 0x111abbb40; frame = (0 0; 320 64); hidden = YES; opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x10ab5ad20>>
| | | | | | | <UIView: 0x111abc960; frame = (0 64; 320 0.5); tag = 11; layer = <CALayer: 0x10ab54110>>
| | | | | | <FloatingControlsView: 0x111abcbb0; frame = (0 524; 320 44); opaque = NO; layer = <CALayer: 0x111a04910>>
| | | | | | | <BlurView: 0x111abd0a0; frame = (0 0; 320 44); autoresize = W+H; layer = <CALayer: 0x10ab506c0>>
| | | | | | | | <_UIBackdropView: 0x111abd280; frame = (0 0; 320 44); opaque = NO; autoresize = W+H; layer = <_UIBackdropViewLayer: 0x111a02e50>>
| | | | | | | | | <_UIBackdropEffectView: 0x111abd730; frame = (0 0; 320 44); clipsToBounds = YES; opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <CABackdropLayer: 0x111a02560>>
| | | | | | | | | <UIView: 0x111abd900; frame = (0 0; 320 44); hidden = YES; opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x10ab4ea30>>
| | | | | | | | <MapsUserTrackingButton: 0x111abee30; baseClass = UIButton; frame = (5 4; 36 36); opaque = NO; tag = 1; layer = <CALayer: 0x10abf7710>>
| | | | | | | | | <UIImageView: 0x121201640; frame = (0 0; 36 36); alpha = 0.1; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x121200b90>>
| | | | | | | | | <UIImageView: 0x111abf970; frame = (5.5 8; 22.5 22.5); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x10abf26d0>>
| | | | | | | | <UIButton: 0x111ac3f70; frame = (142 4; 36 36); opaque = NO; tag = 5; layer = <CALayer: 0x10abdf330>>
| | | | | | | | | <UIImageView: 0x111ad69e0; frame = (8.5 4.5; 19 26.5); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x10ab5e130>>
| | | | | | | | <UIButton: 0x111ac56f0; frame = (279 4; 36 36); opaque = NO; tag = 6; layer = <CALayer: 0x10abda8c0>>
| | | | | | | | | <UIImageView: 0x111ad72e0; frame = (5.5 5.5; 25 25); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x10ab5bf40>>
| | | | | | | <UIView: 0x111abdbb0; frame = (0 -0.5; 320 0.5); layer = <CALayer: 0x111a147f0>>
| | | | | | <UINavigationBar: 0x114b06b80; frame = (0 20; 320 44); opaque = NO; autoresize = W; gestureRecognizers = <NSArray: 0x114b07530>; layer = <CALayer: 0x114b06cf0>>
| | | | | | | <_UINavigationBarBackground: 0x114b06e40; frame = (0 0; 320 44); opaque = NO; autoresize = W; userInteractionEnabled = NO; layer = <CALayer: 0x114b06fa0>>
| | | | | | | | <UIImageView: 0x114b06ff0; frame = (0 44; 320 0.5); userInteractionEnabled = NO; layer = <CALayer: 0x114b07110>>
| | | | | | | <UINavigationItemView: 0x10afc7ba0; frame = (139.5 8; 41.5 27); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x10afc7ca0>>
| | | | | | | | <UILabel: 0x10afc7cc0; frame = (0 4; 41.5 21); text = 'Maps'; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x10afc7e00>>
| | | | | | | <UINavigationButton: 0x114b610a0; frame = (270 8; 42 30); opaque = NO; layer = <CALayer: 0x114b61320>>
| | | | | | | | <UIButtonLabel: 0x114b34180; frame = (0 4; 42 21); text = 'Done'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x114b342d0>>
| | | | | | | <_UINavigationBarBackIndicatorView: 0x114b7efd0; frame = (8 12; 12.5 20.5); alpha = 0; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x114b30520>>
| | | | | <_UILayoutGuide: 0x111abafa0; frame = (0 0; 0 20); hidden = YES; layer = <CALayer: 0x111a218f0>>
| | | | | <_UILayoutGuide: 0x111aaff20; frame = (0 568; 0 0); hidden = YES; layer = <CALayer: 0x10ab70a50>>
| | | | | <UIView: 0x1212b0530; frame = (0 64; 320 504); autoresize = W+H; layer = <CALayer: 0x1212b0180>>
| | | | | | <BlurView: 0x1212af380; frame = (0 231.5; 320 272.5); layer = <CALayer: 0x1212af460>>
| | | | | | | <_UIBackdropView: 0x1212af480; frame = (0 0; 320 272); opaque = NO; autoresize = W+H; layer = <_UIBackdropViewLayer: 0x1212af840>>
| | | | | | | | <_UIBackdropEffectView: 0x1212afb60; frame = (0 0; 320 272); clipsToBounds = YES; opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <CABackdropLayer: 0x1212afc30>>
| | | | | | | | <UIView: 0x1212afc50; frame = (0 0; 320 272); hidden = YES; opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x1212afd10>>
| | | | | | <UITableView: 0x10f1ce000; frame = (0 231.5; 320 272.5); clipsToBounds = YES; opaque = NO; autoresize = W+H; gestureRecognizers = <NSArray: 0x12122c920>; layer = <CALayer: 0x10c8ed850>; contentOffset: {0, 0}>
| | | | | | | <UITableViewWrapperView: 0x12127c430; frame = (0 0; 320 272); autoresize = W+H; layer = <CALayer: 0x10c8aebb0>>
| | | | | | | | <UITableViewCell: 0x10aff4d40; frame = (0 222.5; 320 50); text = 'Data from , others '; clipsToBounds = YES; opaque = NO; autoresize = W; layer = <CALayer: 0x10aff5030>>
| | | | | | | | | <UITableViewCellScrollView: 0x10aff5050; frame = (0 0; 320 50); autoresize = W+H; gestureRecognizers = <NSArray: 0x10aff5470>; layer = <CALayer: 0x10aff5370>; contentOffset: {0, 0}>
| | | | | | | | | | <UITableViewCellContentView: 0x10aff5760; frame = (0 0; 320 49.5); opaque = NO; gestureRecognizers = <NSArray: 0x10aff5a80>; layer = <CALayer: 0x10aff5820>>
| | | | | | | | | | | <UILabel: 0x114baaaa0; frame = (15 0; 290 49.5); text = 'Data from , others '; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x10aff5ae0>>
| | | | | | | | | | <_UITableViewCellSeparatorView: 0x114bab020; frame = (15 49.5; 290 0.5); layer = <CALayer: 0x114baae90>>
| | | | | | | | <UITableViewCell: 0x10aff3740; frame = (0 172.5; 320 50); text = 'Show Traffic'; clipsToBounds = YES; opaque = NO; autoresize = W; layer = <CALayer: 0x10aff3110>>
| | | | | | | | | <UITableViewCellScrollView: 0x10aff3a30; frame = (0 0; 320 50); autoresize = W+H; gestureRecognizers = <NSArray: 0x10aff3e30>; layer = <CALayer: 0x10aff3130>; contentOffset: {0, 0}>
| | | | | | | | | | <UITableViewCellContentView: 0x10aff4120; frame = (0 0; 320 49.5); opaque = NO; gestureRecognizers = <NSArray: 0x10aff4440>; layer = <CALayer: 0x10aff41e0>>
| | | | | | | | | | | <UILabel: 0x10aff44a0; frame = (15 0; 290 49.5); text = 'Show Traffic'; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x10aff45e0>>
| | | | | | | | | | <_UITableViewCellSeparatorView: 0x10aff49c0; frame = (15 49.5; 290 0.5); layer = <CALayer: 0x10aff48e0>>
| | | | | | | | <UITableViewCell: 0x10aff2120; frame = (0 115; 320 50); text = 'Report a Problem'; clipsToBounds = YES; opaque = NO; autoresize = W; layer = <CALayer: 0x10aff2410>>
| | | | | | | | | <UITableViewCellScrollView: 0x10aff2430; frame = (0 0; 320 50); autoresize = W+H; gestureRecognizers = <NSArray: 0x10aff2850>; layer = <CALayer: 0x10aff2750>; contentOffset: {0, 0}>
| | | | | | | | | | <UITableViewCellContentView: 0x10aff2b40; frame = (0 0; 320 49.5); opaque = NO; gestureRecognizers = <NSArray: 0x10aff2e60>; layer = <CALayer: 0x10aff2c00>>
| | | | | | | | | | | <UILabel: 0x10aff2ec0; frame = (15 0; 290 49.5); text = 'Report a Problem'; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x10aff3000>>
| | | | | | | | | | <_UITableViewCellSeparatorView: 0x10aff3380; frame = (0 49.5; 320 0.5); hidden = YES; layer = <CALayer: 0x10aff3450>>
| | | | | | | | <UITableViewCell: 0x10afd7d70; frame = (0 57.5; 320 50); text = 'Drop a Pin'; clipsToBounds = YES; opaque = NO; autoresize = W; layer = <CALayer: 0x114ba9a60>>
| | | | | | | | | <UITableViewCellScrollView: 0x10aff1d60; frame = (0 0; 320 50); autoresize = W+H; gestureRecognizers = <NSArray: 0x114b0b490>; layer = <CALayer: 0x114b0b790>; contentOffset: {0, 0}>
| | | | | | | | | | <UITableViewCellContentView: 0x10afd6390; frame = (0 0; 320 49.5); opaque = NO; gestureRecognizers = <NSArray: 0x114ba9640>; layer = <CALayer: 0x10afd4fb0>>
| | | | | | | | | | | <UILabel: 0x114b00d10; frame = (15 0; 290 49.5); text = 'Drop a Pin'; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x114b00e50>>
| | | | | | | | | | <_UITableViewCellSeparatorView: 0x10afd85c0; frame = (0 49.5; 320 0.5); hidden = YES; layer = <CALayer: 0x10afd58b0>>
| | | | | | | | <UITableViewCell: 0x114b3fa00; frame = (0 0; 320 50); clipsToBounds = YES; opaque = NO; autoresize = W; layer = <CALayer: 0x114b3ff30>>
| | | | | | | | | <UITableViewCellScrollView: 0x10afd5160; frame = (0 0; 320 50); autoresize = W+H; gestureRecognizers = <NSArray: 0x10afd5bc0>; layer = <CALayer: 0x10afd55c0>; contentOffset: {0, 0}>
| | | | | | | | | | <UITableViewCellContentView: 0x10afd62d0; frame = (0 0; 320 49.5); opaque = NO; gestureRecognizers = <NSArray: 0x10afd8200>; layer = <CALayer: 0x10afd6550>>
| | | | | | | | | | | <UISegmentedControl: 0x10afd8260; frame = (20 10; 280 29); opaque = NO; autoresize = LM+RM+TM+BM; layer = <CALayer: 0x10afd8540>>
| | | | | | | | | | | | <UISegment: 0x10afee6d0; frame = (187 0; 93 29); opaque = NO; layer = <CALayer: 0x10afee540>>
| | | | | | | | | | | | | <UISegmentLabel: 0x10afee850; frame = (22 5.5; 49 16); text = 'Satellite'; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x10afee520>>
| | | | | | | | | | | | | <UIImageView: 0x10afef570; frame = (93 0; 1 29); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; tag = -1030; layer = <CALayer: 0x10afef510>>
| | | | | | | | | | | | <UISegment: 0x10afed880; frame = (93 0; 93 29); opaque = NO; layer = <CALayer: 0x10afeccf0>>
| | | | | | | | | | | | | <UISegmentLabel: 0x10afedb00; frame = (26.5 5.5; 40 16); text = 'Hybrid'; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x10afeccd0>>
| | | | | | | | | | | | | <UIImageView: 0x10afee270; frame = (93 0; 1 29); opaque = NO; autoresize = LM; userInteractionEnabled = NO; tag = -1030; layer = <CALayer: 0x10afee210>>
| | | | | | | | | | | | <UISegment: 0x114b00ab0; frame = (0 0; 92 29); opaque = NO; layer = <CALayer: 0x10afb5380>>
| | | | | | | | | | | | | <UISegmentLabel: 0x114b0b7b0; frame = (18.5 5.5; 55 16); text = 'Standard'; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x114b6d6a0>>
| | | | | | | | | | | | | <UIImageView: 0x10afed530; frame = (92 0; 1 29); opaque = NO; autoresize = LM; userInteractionEnabled = NO; tag = -1030; layer = <CALayer: 0x114b342f0>>
| | | | | | | | | | <_UITableViewCellSeparatorView: 0x10aff1640; frame = (0 49.5; 320 0.5); hidden = YES; layer = <CALayer: 0x10aff1710>>
| | | | | | | <UIImageView: 0x10afd9470; frame = (0 269; 320 3); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x114b041d0>>
| | | | | | | <HeaderView: 0x114b134c0; frame = (0 50; 320 7.5); opaque = NO; autoresize = W; layer = <CALayer: 0x114bab510>>
| | | | | | | | <CALayer: 0x114bab530> (layer)
| | | | | | | | <CALayer: 0x114b13ab0> (layer)
| | | | | | | <HeaderView: 0x114b13ff0; frame = (0 107.5; 320 7.5); opaque = NO; autoresize = W; layer = <CALayer: 0x114b141b0>>
| | | | | | | | <CALayer: 0x114b141d0> (layer)
| | | | | | | | <CALayer: 0x114b14320> (layer)
| | | | | | | <HeaderView: 0x114b78a90; frame = (0 165; 320 7.5); opaque = NO; autoresize = W; layer = <CALayer: 0x114b13ec0>>
| | | | | | | | <CALayer: 0x114b78b50> (layer)
| | | | | | | | <CALayer: 0x114b78ca0> (layer)
| | | | | | | <UIImageView: 0x10afd9810; frame = (316 275; 3 273); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x10afea2a0>>
| | | | | | <UIView: 0x1212b08a0; frame = (0 0; 320 231.5); autoresize = W+H; gestureRecognizers = <NSArray: 0x1212b0b50>; layer = <CALayer: 0x1212b0960>>
| | <UINavigationBar: 0x10af6e520; frame = (0 -44; 320 44); hidden = YES; opaque = NO; autoresize = W; gestureRecognizers = <NSArray: 0x10af6ae90>; layer = <CALayer: 0x10af6e750>>
| | | <_UINavigationBarBackground: 0x10af6f460; frame = (0 -20; 320 64); opaque = NO; autoresize = W; userInteractionEnabled = NO; layer = <CALayer: 0x10af6f740>>
| | | | <_UIBackdropView: 0x111acc810; frame = (0 0; 320 64); opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <_UIBackdropViewLayer: 0x10abbdfc0>>
| | | | | <_UIBackdropEffectView: 0x111acb540; frame = (0 0; 320 64); clipsToBounds = YES; opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <CABackdropLayer: 0x111abc540>>
| | | | | <UIView: 0x111accc20; frame = (0 0; 320 64); hidden = YES; opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x10abbd9f0>>
| | | | <UIImageView: 0x10af6aa60; frame = (0 64; 320 0.5); userInteractionEnabled = NO; layer = <CALayer: 0x10af6ab80>>
| | | <_UINavigationBarBackIndicatorView: 0x10af72d40; frame = (8 12; 12.5 20.5); alpha = 0; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x10af72ac0>>
You can see in the view hierarchy, that there is the map part, and then there is a view with all the content of the settings/info, including a navigation bar and a table view with all the cells. Let's look at how the view controllers are set up:
po [0x1212b0530 _viewDelegate]
<SettingsViewControllerPhone: 0x12127bea0>
po [[0x1212b0530 _viewDelegate] parentViewController]
<MainChromeViewController: 0x10af511e0>
MainChromeViewController is the main view controller of the maps app. So, as you can see, it is a child view controller of the main view controller. It is animated in place when you tab the button.
It's either a custom controller with a UIToolbar at the top, or it is a UIViewController embedded into a UINavigationController.

Recreating Add Contact screen

I am trying to recreate the Add Contact screen. I am able to this with a UITableViewController, however, I am unable to set the width of the cells to make room for the Add Photo Button. Any ideas?
If you ever want to see what a standard view is doing, write an app that presents the view, run it in the simulator, pause the debugger when the view comes up, and then type the following command in the debugger:
po [[UIWindow keyWindow] recursiveDescription]
When you do that, you'll see a listing like so:
(lldb) po [[UIWindow keyWindow] recursiveDescription]
$0 = 0x075b38c0 <UIWindow: 0x7582f20; frame = (0 0; 320 480); layer = <UIWindowLayer: 0x7581a40>>
| <UILayoutContainerView: 0x7593940; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0x7593a00>>
| | <UINavigationTransitionView: 0x75961a0; frame = (0 0; 320 480); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x7596270>>
| | | <UIViewControllerWrapperView: 0x81867b0; frame = (0 64; 320 416); autoresize = W+H; layer = <CALayer: 0x8186860>>
| | | | <ABPersonContainerView: 0x75a14f0; frame = (0 0; 320 416); autoresize = W+H; layer = <CALayer: 0x75a15f0>>
| | | | | <ABPersonTableView: 0x7b66e00; baseClass = UITableView; frame = (0 0; 320 416); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x75a2050>; layer = <CALayer: 0x75a1b50>; contentOffset: {0, 0}>
| | | | | | <UITableViewBackgroundView: 0x75a2a50; frame = (0 0; 320 416); layer = <CALayer: 0x75a2ae0>>
| | | | | | | <UIImageView: 0x75a2c60; frame = (0 0; 320 416); opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x75a35b0>>
| | | | | | | <UIView: 0x75a2da0; frame = (0 0; 320 416); autoresize = W+H; layer = <CALayer: 0x75a35e0>>
| | | | | | <ABChameleonCell: 0x8183e90; baseClass = UITableViewCell; frame = (0 452; 320 46); text = 'add new address'; hidden = YES; autoresize = W; tag = 11; layer = <CALayer: 0x8182fd0>>
| | | | | | | <UIGroupTableViewCellBackground: 0x8184950; frame = (41 0; 270 46); autoresize = W; layer = <CALayer: 0x81849d0>>
| | | | | | | <UITableViewCellContentView: 0x8184060; frame = (42 1; 268 43); gestureRecognizers = <NSArray: 0x8184410>; layer = <CALayer: 0x81841d0>>
| | | | | | | | <UILabel: 0x8184460; frame = (10 0; 248 43); text = 'add new address'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x81844f0>>
| | | | | | | <UITableViewCellEditControl: 0x8185400; frame = (0 0; 41 46); opaque = NO; layer = <CALayer: 0x8185480>>
| | | | | | | | <UIImageView: 0x8185b50; frame = (6 9; 29 29); opaque = NO; userInteractionEnabled = NO; tag = 1; layer = <CALayer: 0x8184c90>>
| | | | | | | <UIImageView: 0x81853a0; frame = (42 1; 268 8); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8185890>>
| | | | | | <ABMultiCell: 0x81804f0; baseClass = UITableViewCell; frame = (0 391; 320 46); autoresize = W; tag = 11; layer = <CALayer: 0x81803d0>>
| | | | | | | <UIGroupTableViewCellBackground: 0x8182a60; frame = (41 0; 270 46); autoresize = W; layer = <CALayer: 0x8182ae0>>
| | | | | | | <UITableViewCellContentView: 0x8180440; frame = (42 1; 268 43); gestureRecognizers = <NSArray: 0x8180760>; layer = <CALayer: 0x8180630>>
| | | | | | | | <ABMultiCellContentView_Simple: 0x81808f0; frame = (0 0; 268 43); clipsToBounds = YES; layer = <CALayer: 0x81809b0>>
| | | | | | | | | <UILabel: 0x8180a90; frame = (5 14; 72 17); text = 'home page'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x81809f0>>
| | | | | | | | | <ABDividerView: 0x8180de0; frame = (79 0; 1 44); layer = <CALayer: 0x8180d60>>
| | | | | | | | | | <ABSteadfastLineView: 0x8180ce0; frame = (0 0; 1 44); layer = <CALayer: 0x8180d90>>
| | | | | | | | | <ABHighlightingTextField: 0x8180f80; baseClass = UITextField; frame = (83 12; 180 21); clipsToBounds = YES; opaque = NO; gestureRecognizers = <NSArray: 0x81814f0>; layer = <CALayer: 0x81810f0>>
| | | | | | | | | | <UITextFieldLabel: 0x8182330; frame = (0 0; 180 19); text = 'URL'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x81823c0>>
| | | | | | | | <UILabel: 0x8182e00; frame = (0 0; 0 0); clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x8182e90>>
| | | | | | | <UITableViewCellEditControl: 0x8183560; frame = (0 0; 41 46); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8183c60>>
| | | | | | | | <UIImageView: 0x8183c90; frame = (20 24; 0 0); userInteractionEnabled = NO; tag = 1; layer = <CALayer: 0x8183cf0>>
| | | | | | | <UIImageView: 0x81834b0; frame = (42 1; 268 8); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8183ac0>>
| | | | | | <ABMultiCell: 0x817d210; baseClass = UITableViewCell; frame = (0 331; 320 45); autoresize = W; tag = 12; layer = <CALayer: 0x817d110>>
| | | | | | | <UIGroupTableViewCellBackground: 0x817f960; frame = (41 0; 270 45); autoresize = W; layer = <CALayer: 0x817f9e0>>
| | | | | | | | <UIView: 0x817fa10; frame = (1 0; 268 1); hidden = YES; autoresize = W; layer = <CALayer: 0x817fa70>>
| | | | | | | <UITableViewCellContentView: 0x817d140; frame = (42 0; 248 43); gestureRecognizers = <NSArray: 0x817d470>; layer = <CALayer: 0x817d1a0>>
| | | | | | | | <ABMultiCellContentView_Simple: 0x817d790; frame = (0 0; 248 43); text = 'Default'; clipsToBounds = YES; layer = <CALayer: 0x817d850>>
| | | | | | | | | <UILabel: 0x817d8d0; frame = (5 14; 72 17); text = 'text tone'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x817d6c0>>
| | | | | | | | | <ABHighlightingTextField: 0x817db80; baseClass = UITextField; frame = (83 12; 160 21); text = 'Default'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; gestureRecognizers = <NSArray: 0x817e0b0>; layer = <CALayer: 0x817d8a0>>
| | | | | | | | | | <UITextFieldLabel: 0x817dcf0; frame = (0 0; 160 19); text = 'Default'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x817dd80>>
| | | | | | | | <UILabel: 0x81801f0; frame = (0 0; 0 0); clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x8180280>>
| | | | | | | <UITableViewCellEditControl: 0x817fde0; frame = (0 0; 41 45); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x817fe60>>
| | | | | | | | <UIImageView: 0x817fe90; frame = (20 23; 0 0); userInteractionEnabled = NO; tag = 1; layer = <CALayer: 0x817fef0>>
| | | | | | | <UIButton: 0x817d4c0; frame = (280 0; 30 43); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x817d580>>
| | | | | | | | <UIImageView: 0x817f420; frame = (10 15; 10 13); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x817f480>>
| | | | | | | <UIView: 0x817fb80; frame = (42 0; 268 1); userInteractionEnabled = NO; layer = <CALayer: 0x817fbe0>>
| | | | | | <ABMultiCell: 0x8143ed0; baseClass = UITableViewCell; frame = (0 286; 320 45); autoresize = W; tag = 12; layer = <CALayer: 0x813a1a0>>
| | | | | | | <UIGroupTableViewCellBackground: 0x817ad90; frame = (41 0; 270 45); autoresize = W; layer = <CALayer: 0x81798f0>>
| | | | | | | | <UIView: 0x817ae10; frame = (1 44; 268 1); hidden = YES; autoresize = W+TM; layer = <CALayer: 0x817ae70>>
| | | | | | | <UITableViewCellContentView: 0x8143200; frame = (42 1; 248 43); gestureRecognizers = <NSArray: 0x8141ba0>; layer = <CALayer: 0x8140760>>
| | | | | | | | <ABMultiCellContentView_Simple: 0x8144120; frame = (0 0; 248 43); text = 'Default'; clipsToBounds = YES; layer = <CALayer: 0x8157150>>
| | | | | | | | | <UILabel: 0x813f890; frame = (5 14; 72 17); text = 'ringtone'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x8157510>>
| | | | | | | | | <ABHighlightingTextField: 0x81412d0; baseClass = UITextField; frame = (83 12; 160 21); text = 'Default'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; gestureRecognizers = <NSArray: 0x817b320>; layer = <CALayer: 0x813d910>>
| | | | | | | | | | <UITextFieldLabel: 0x81706b0; frame = (0 0; 160 19); text = 'Default'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8156a20>>
| | | | | | | | <UILabel: 0x817cdf0; frame = (0 0; 0 0); clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x817ce80>>
| | | | | | | <UITableViewCellEditControl: 0x8153b70; frame = (0 0; 41 45); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8153bf0>>
| | | | | | | | <UIImageView: 0x817c040; frame = (20 23; 0 0); userInteractionEnabled = NO; tag = 1; layer = <CALayer: 0x8153c20>>
| | | | | | | <UIButton: 0x8179120; frame = (280 1; 30 43); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8145d80>>
| | | | | | | | <UIImageView: 0x8152f20; frame = (10 15; 10 13); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8141820>>
| | | | | | | <UIImageView: 0x813a780; frame = (42 1; 268 8); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x817cc30>>
| | | | | | <ABMultiCell: 0x75bda30; baseClass = UITableViewCell; frame = (0 225; 320 46); autoresize = W; tag = 11; layer = <CALayer: 0x75bd910>>
| | | | | | | <UIGroupTableViewCellBackground: 0x75c0300; frame = (41 0; 270 46); autoresize = W; layer = <CALayer: 0x75c0380>>
| | | | | | | <UITableViewCellContentView: 0x75bd980; frame = (42 1; 268 43); gestureRecognizers = <NSArray: 0x75bdde0>; layer = <CALayer: 0x75bdc00>>
| | | | | | | | <ABMultiCellContentView_Simple: 0x75bdf70; frame = (0 0; 268 43); clipsToBounds = YES; layer = <CALayer: 0x75be030>>
| | | | | | | | | <UILabel: 0x75be0d0; frame = (5 14; 72 17); text = 'home'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x75be070>>
| | | | | | | | | <ABDividerView: 0x75be680; frame = (79 0; 1 44); layer = <CALayer: 0x75be4d0>>
| | | | | | | | | | <ABSteadfastLineView: 0x75be320; frame = (0 0; 1 44); layer = <CALayer: 0x75be500>>
| | | | | | | | | <ABHighlightingTextField: 0x75be820; baseClass = UITextField; frame = (83 12; 180 21); clipsToBounds = YES; opaque = NO; gestureRecognizers = <NSArray: 0x75bed90>; layer = <CALayer: 0x75be990>>
| | | | | | | | | | <UITextFieldLabel: 0x75bfbd0; frame = (0 0; 180 19); text = 'Email'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x75bfc60>>
| | | | | | | | <UILabel: 0x813ad50; frame = (0 0; 0 0); clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x813f2d0>>
| | | | | | | <UITableViewCellEditControl: 0x813bdb0; frame = (0 0; 41 46); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x81397a0>>
| | | | | | | | <UIImageView: 0x8140ee0; frame = (20 24; 0 0); userInteractionEnabled = NO; tag = 1; layer = <CALayer: 0x813bf90>>
| | | | | | | <UIImageView: 0x817a3f0; frame = (42 1; 268 8); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8170920>>
| | | | | | <ABMultiCell: 0x75b7990; baseClass = UITableViewCell; frame = (0 164; 320 46); autoresize = W; tag = 11; layer = <CALayer: 0x75b7890>>
| | | | | | | <UIGroupTableViewCellBackground: 0x75bb650; frame = (41 0; 270 46); autoresize = W; layer = <CALayer: 0x75bb750>>
| | | | | | | <UITableViewCellContentView: 0x75b78e0; frame = (42 1; 268 43); gestureRecognizers = <NSArray: 0x75b7d40>; layer = <CALayer: 0x75b7b20>>
| | | | | | | | <ABMultiCellContentView_Simple: 0x75b7ed0; frame = (0 0; 268 43); clipsToBounds = YES; layer = <CALayer: 0x75b7fe0>>
| | | | | | | | | <UILabel: 0x75b86b0; frame = (5 14; 72 17); text = 'mobile'; clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x75b8740>>
| | | | | | | | | <ABDividerView: 0x75b8a40; frame = (79 0; 1 44); layer = <CALayer: 0x75b89c0>>
| | | | | | | | | | <ABSteadfastLineView: 0x75b8ab0; frame = (0 0; 1 44); layer = <CALayer: 0x75b89f0>>
| | | | | | | | | <ABHighlightingTextField: 0x75b8c40; baseClass = UITextField; frame = (83 12; 180 21); clipsToBounds = YES; opaque = NO; gestureRecognizers = <NSArray: 0x75b91b0>; layer = <CALayer: 0x75b8db0>>
| | | | | | | | | | <UITextFieldLabel: 0x75b9ff0; frame = (0 0; 180 19); text = 'Phone'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x75ba080>>
| | | | | | | | <UILabel: 0x75bd5f0; frame = (0 0; 0 0); clipsToBounds = YES; userInteractionEnabled = NO; layer = <CALayer: 0x75bd680>>
| | | | | | | <UITableViewCellEditControl: 0x75bba70; frame = (0 0; 41 46); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x75bbb40>>
| | | | | | | | <UIImageView: 0x75bc980; frame = (20 24; 0 0); userInteractionEnabled = NO; tag = 1; layer = <CALayer: 0x75bbd90>>
| | | | | | | <UIImageView: 0x75bc320; frame = (42 1; 268 8); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x75bbea0>>
| | | | | | <UIView: 0x817afb0; frame = (0 0; 320 164); layer = <CALayer: 0x817b010>>
| | | | | | | <ABPersonTableHeaderView: 0x75a6c60; frame = (0 0; 320 164); clipsToBounds = YES; layer = <CALayer: 0x75a6d40>>
| | | | | | | | <UITableView: 0x7b69200; frame = (90 15; 222 134); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x75a7360>; layer = <CALayer: 0x75a6f90>; contentOffset: {0, 0}>
| | | | | | | | | <ABMultiCell: 0x8178a20; baseClass = UITableViewCell; frame = (0 0; 222 134); autoresize = W; layer = <CALayer: 0x8178b90>>
| | | | | | | | | | <UIGroupTableViewCellBackground: 0x8188af0; frame = (1 0; 220 134); autoresize = W; layer = <CALayer: 0x8188b70>>
| | | | | | | | | | <UITableViewCellContentView: 0x8178ed0; frame = (2 1; 218 131); gestureRecognizers = <NSArray: 0x8179440>; layer = <CALayer: 0x81790c0>>
| | | | | | | | | | | <ABMultiCellContentView_Name: 0x75aa690; frame = (0 0; 218 131); clipsToBounds = YES; layer = <CALayer: 0x75aa7f0>>
| | | | | | | | | | | | <ABHighlightingTextField: 0x75af0f0; baseClass = UITextField; frame = (3 12; 210 21); clipsToBounds = YES; opaque = NO; tag = 1; gestureRecognizers = <NSArray: 0x75b10f0>; layer = <CALayer: 0x75af2b0>>
| | | | | | | | | | | | | <UITextFieldLabel: 0x75b5d50; frame = (-8 0; 210 19); text = 'First'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x759c7b0>>
| | | | | | | | | | | | <ABHighlightingTextField: 0x75b3450; baseClass = UITextField; frame = (3 56; 210 21); clipsToBounds = YES; opaque = NO; tag = 2; gestureRecognizers = <NSArray: 0x75b3c20>; layer = <CALayer: 0x75b35c0>>
| | | | | | | | | | | | | <UITextFieldLabel: 0x75b6300; frame = (-8 0; 210 19); text = 'Last'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x75b6390>>
| | | | | | | | | | | | <ABDividerView: 0x75b4c20; frame = (0 44; 218 2); layer = <CALayer: 0x75b4ce0>>
| | | | | | | | | | | | | <ABSteadfastLineView: 0x75b4f50; frame = (0 0; 218 1); layer = <CALayer: 0x75b4fe0>>
| | | | | | | | | | | | | <ABSteadfastLineView: 0x7582ad0; frame = (0 1; 218 1); layer = <CALayer: 0x754e520>>
| | | | | | | | | | | | <ABHighlightingTextField: 0x75b0f10; baseClass = UITextField; frame = (3 100; 210 21); clipsToBounds = YES; opaque = NO; tag = 3; gestureRecognizers = <NSArray: 0x75547e0>; layer = <CALayer: 0x7555f90>>
| | | | | | | | | | | | | <UITextFieldLabel: 0x75b6600; frame = (-8 0; 210 19); text = 'Company'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x75b6690>>
| | | | | | | | | | | | <ABDividerView: 0x7594010; frame = (0 88; 218 2); layer = <CALayer: 0x7581a10>>
| | | | | | | | | | | | | <ABSteadfastLineView: 0x75a7300; frame = (0 0; 218 1); layer = <CALayer: 0x75905b0>>
| | | | | | | | | | | | | <ABSteadfastLineView: 0x75aa790; frame = (0 1; 218 1); layer = <CALayer: 0x7592ba0>>
| | | | | | | | | | <UIImageView: 0x8189540; frame = (2 1; 218 8); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8189b50>>
| | | | | | | | <ABPersonImageView: 0x75a8b80; baseClass = UIControl; frame = (9 15; 68 68); autoresize = RM+BM; gestureRecognizers = <NSArray: 0x75a94b0>; layer = <CALayer: 0x75a8c90>>
| | | | | | | | | <ABClippingImageView: 0x817b340; frame = (0 0; 68 68); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x75ac9d0>>
| | | | | | | | <ABPersonNameDisplayView: 0x81796f0; baseClass = UIControl; frame = (89 15; 222 56); alpha = 0; autoresize = W; gestureRecognizers = <NSArray: 0x8179ac0>; layer = <CALayer: 0x81797f0>>
| | | | | | | | | <UILabel: 0x8179d80; frame = (0 28; 0 0); clipsToBounds = YES; autoresize = W; userInteractionEnabled = NO; layer = <CALayer: 0x8179ed0>>
| | | | | | | | | <UILabel: 0x817a2c0; frame = (0 0; 222 0); clipsToBounds = YES; autoresize = W; userInteractionEnabled = NO; layer = <CALayer: 0x817a350>>
| | | | | | <UIImageView: 0x7595250; frame = (1 408; 318 7); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x759eb20>>
| | | | | | <UIImageView: 0x759fd30; frame = (312 1; 7 290); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x759f080>>
| | <UINavigationBar: 0x7593b40; frame = (0 20; 320 44); autoresize = W; gestureRecognizers = <NSArray: 0x7595b40>; layer = <CALayer: 0x7593c40>>
| | | <_UINavigationBarBackground: 0x7593fa0; frame = (0 0; 320 44); opaque = NO; autoresize = W; userInteractionEnabled = NO; layer = <CALayer: 0x7594080>>
| | | | <UIImageView: 0x75947b0; frame = (0 44; 320 3); opaque = NO; autoresize = W+TM; userInteractionEnabled = NO; layer = <CALayer: 0x7594810>>
| | | <UINavigationItemView: 0x7596ac0; frame = (98 9; 123 27); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x7596b90>>
| | | <UINavigationButton: 0x759b3d0; frame = (5 7; 60 30); opaque = NO; layer = <CALayer: 0x759b520>>
| | | | <UIImageView: 0x759d230; frame = (0 0; 60 30); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x759d290>>
| | | | <UIButtonLabel: 0x759bf90; frame = (10 7; 40 15); text = 'Cancel'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x759c080>>
| | | <UINavigationButton: 0x759e860; frame = (265 7; 50 30); opaque = NO; layer = <CALayer: 0x759e950>>
| | | | <UIImageView: 0x759f0b0; frame = (0 0; 50 30); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x759f110>>
| | | | <UIButtonLabel: 0x759ea00; frame = (10 7; 30 15); text = 'Done'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x759eaf0>>
While there's a lot there, I think you'll see that this tableview's first cell is a large one with the "add photo" image and another, nested tableview to its right.
But as you discovered, if you're just trying to add a contact, ABNewPersonViewController provides the necessary functionality (in fact, that's what I used to create the above recursive description). When you posted this question, I thought you were just trying to better understand how this UI was generated. But as always, if you can use the existing API, so much the better.

UIView subviews not showing up

In my subclass of UIView (which I have instantiated in Interface Builder), has a couple buttons as subviews that I add to my view in the initWithCoder method like so:
theButton = [UIButton buttonWithType:UIButtonTypeCustom];
[theButton setFrame:CGRectMake([UIScreen mainScreen].bounds.size.height-150-10, 289, 150, 21)];
[theButton.titleLabel setTextAlignment:UITextAlignmentRight];
[theButton setOpaque:YES];
[theButton.titleLabel setFont:[UIFont fontWithName:#"MyFont" size:32.0]];
[theButton.titleLabel setTextColor:[UIColor redColor]];
[theButton.titleLabel setText:#"text"];
[self addSubview:theButton];
[theButton addTarget:myTarget action:#selector(pause) forControlEvents:UIControlEventTouchUpInside];
But the button will not draw as it is supposed to. If I set a breakpoint in drawRect:, and po [self subviews] with llvm, I get this output.
$0 = 0x0c93e860 <__NSArrayM 0xc93e860>(
<UIButton: 0xc93d910; frame = (10 289; 150 21); alpha = 0.5; layer = <CALayer: 0xc93d4a0>>,
<UIButton: 0xc93e2d0; frame = (408 289; 150 21); layer = <CALayer: 0xc93e390>>
)
So why isn't my button showing up?
Edit: my superview's recursiveDescription:
<UIView: 0xa46b220; frame = (0 0; 320 568); transform = [0, -1, 1, 0, 0, 0]; autoresize = RM+BM; layer = <CALayer: 0xa46b280>>
| <MyView: 0xa168710; frame = (0 0; 568 320); autoresize = W+H; layer = <CALayer: 0xa1687d0>>
| | <UIButton: 0xa16c160; frame = (10 289; 150 21); alpha = 0.5; layer = <CALayer: 0xa16bcc0>>
| | | <UIButtonLabel: 0xa16c3e0; frame = (0 0; 0 0); clipsToBounds = YES; hidden = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0xa16c480>>
| | <UIButton: 0xa16cb00; frame = (408 289; 150 21); layer = <CALayer: 0xa16cbc0>>
| | | <UIButtonLabel: 0xa16c7e0; frame = (0 0; 0 0); clipsToBounds = YES; hidden = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0xa16c880>>
Well, my guess is that your button is showing up, but you made it a custom button with no text for the normal state (and because you are not using any background image or color, it seems invisible).
UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setTitle:#"Text" forState:UIControlStateNormal];
Instead of calling setText on the button's label, try sending setTitle:forState to the button (not its title label) instead:
[theButton setTitle:#"text" forState:UIControlStateNormal]

Trying to customize ABPersonViewController - can't loop through its subviews

I'm trying to take advantage of ABPersonViewController's simplicity while at the same time customizing it's appearance slightly to match the look and feel of my app.
I subclassed ABPersonViewController, and using this technique, I loop through the view hierarchy of ABPersonViewController, and here is my output:
UIView: 0x5a45d80; frame = (0 0; 320 416); autoresize = W+H; layer = >
| ABPersonTableView: 0x6041a00; baseClass = UITableView; frame = (0 0; 320 416); clipsToBounds = YES; autoresize = W+H; layer = ; contentOffset: {0, 0}>
| | ABMultiCell: 0x5a50080; baseClass = UITableViewCell; frame = (0 94; 320 45); autoresize = W; tag = 10; layer = >
| | | UIGroupTableViewCellBackground: 0x5a678d0; frame = (9 0; 302 45); autoresize = W; layer = >
| | | UITableViewCellContentView: 0x5a62670; frame = (10 1; 300 43); layer = >
| | | | ABMultiCellContentView_Simple: 0x5a4fef0; frame = (0 0; 300 43); text = '(555) 555-5555'; clipsToBounds = YES; layer = >
| | | | | UILabel: 0x5a61590; frame = (5 14.54; 70 16); text = 'mobile'; clipsToBounds = YES; userInteractionEnabled = NO; layer = >
| | | | | ABDividerView: 0x5a62ff0; frame = (79 0; 1 44); alpha = 0; layer = >
| | | | | | ABSteadfastLineView: 0x5a53ab0; frame = (0 0; 1 44); layer = >
| | | | | ABHighlightingTextField: 0x5a53c30; baseClass = UITextField; frame = (85 12; 210 21); text = '(555) 555-5555'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = >
| | | | | | UITextFieldLabel: 0x5a53db0; frame = (0 0; 210 19); text = '(530) 305-0835'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = >
| | UIView: 0x5a5b300; frame = (0 0; 320 94); layer = >
| | | ABPersonTableHeaderView: 0x5a444b0; frame = (0 0; 320 94); clipsToBounds = YES; autoresize = W; layer = >
| | | | ABPersonImageView: 0x5a449c0; baseClass = UIControl; frame = (19 15; 64 64); clipsToBounds = YES; autoresize = RM+BM; layer = >
| | | | | ABClippingImageView: 0x5a6aae0; frame = (0 0; 64 64); opaque = NO; userInteractionEnabled = NO; layer = >
| | | | | ABImageWellLabelView: 0x5a6c0b0; frame = (0 0; 64 64); alpha = 0; opaque = NO; userInteractionEnabled = NO; layer = >
| | | | ABPersonNameEditingViewContainer: 0x5a4a9e0; frame = (101 15; 530 64); alpha = 0; autoresize = W+BM; layer = >
| | | | | ABMultiCellContentView_Name: 0x5a4b480; frame = (1 0; 208 64); clipsToBounds = YES; layer = >
| | | | | | ABHighlightingTextField: 0x5a4d7c0; baseClass = UITextField; frame = (-5 12; 10 21); text = 'First Name'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; tag = 1; layer = >
| | | | | | | UITextFieldLabel: 0x5a4b3e0; frame = (-10 0; 10 19); text = 'First Name'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = >
| | | | | | ABHighlightingTextField: 0x5a50a90; baseClass = UITextField; frame = (-5 56; 10 21); text = 'Last Name'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; tag = 2; layer = >
| | | | | | | UITextFieldLabel: 0x5a4e5d0; frame = (-10 0; 10 19); text = 'Last Name'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = >
| | | | | | ABDividerView: 0x5a52300; frame = (0 44; 0 1); layer = >
| | | | | | | ABSteadfastLineView: 0x5a525d0; frame = (0 0; 0 1); layer = >
| | | | | | ABHighlightingTextField: 0x5a52400; baseClass = UITextField; frame = (-5 100; 10 21); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; tag = 3; layer = >
| | | | | | | UITextFieldLabel: 0x5a5a4e0; frame = (-8 0; 10 19); text = 'Company'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = >
| | | | | | ABDividerView: 0x5a53f00; frame = (0 88; 0 1); layer = >
| | | | | | | ABSteadfastLineView: 0x5a53f80; frame = (0 0; 0 1); layer = >
| | | | ABPersonNameDisplayView: 0x5a45cf0; baseClass = UIControl; frame = (97 15; 204 64); autoresize = W; layer = >
| | | | | UILabel: 0x5a4bbd0; frame = (0 21; 109 23); text = 'First Name Last Name'; clipsToBounds = YES; autoresize = W; userInteractionEnabled = NO; layer = >
| | | | | UILabel: 0x5a4c020; frame = (0 0; 204 0); clipsToBounds = YES; autoresize = W; userInteractionEnabled = NO; layer = >
| | UIImageView: 0xcc032a0; frame = (0 409; 320 7); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = >
| | UIImageView: 0xcc03350; frame = (313 262; 7 154); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = >
Sweet! So I should be able to recursively loop though the root UIView's subviews, and alter to my hearts content.
The problem is, that when performing this loop, the root UIView only shows one subview
(ABPersonTableView), and I can not go any deeper.
Any ideas why? Is ABPersonTableView a private class that hides everything it creates/contains?
I am able to alter the background color of the table by doing this inside my recursive loop:
if ([subview isKindOfClass:[UITableView class]]) {
((UITableView *)subview).backgroundColor = [UIColor purpleColor];
}
However, I can't access any of the UILabels because I can't get to any of the subviews of ABPersonTableView.
Any ideas?
You are stuck because Apple offers only two ways:
Apple's built-in, automatic, super easy look and feel way (which is non-cutomizeable)
Roll-your-own you do everything using low level calls to the AddressBook
ABPersonViewController and its subviews aren't meant to be modified and doing so isn't guaranteed to work with future software updates.
The reason is that Apple wants a consistent look and feel.
If you really need to match your apps look and feel, you will have to go with method 2) above and re-implement the whole thing from scratch. This is not necessarily hard, but certainly time consuming.
Edit: see comments for final solution to poster's Q
Note that Apple explicitly warns against modifying the appearance of standard user interface elements and/or manipulating the subviews of standard views and controls. If you're just building this for yourself, no problem, but prepare for rejection if you're planning on submitting this app to the app store.
All the same, it's a good question.
You can access ABPersonTableView in viewDidLoad after calling layoutSubViews :)
example:
- (void)viewDidLoad
{
[super viewDidLoad];
// get ABPersonTableView and forced it layout subviews
UIView *personTableView = [self.view.subviews objectAtIndex:0];
[personTableView layoutSubviews];
// loop through subviews and customize all exceps contacts image
NSArray *subViews = personTableView.subviews;
UIView *view;
for(int i = 0; i < subViews.count-1; i++) {
view = [subViews objectAtIndex:i];
//...customize cells
}
}
Are you doing this in -viewDidLoad? You might have to wait until the table view’s finished calling into whatever it internally uses as a data source to create all its cells. You could do that by calling -reloadData on the table, or by waiting one cycle (using -performSelector:withObject:afterDelay: with a delay of 0), and then trying to mess with its cell contents.

Where Does A UIAlertView Live While Not Dismissed

Does anyone know in whose subview an active UIAlertView is located or how to find the thread in which it is running?
If you dump the contents of the windows property and all subviews of all views you can see that the UIAlertView is in a separate window that overlays the main window. Here I have a navbar with a viewcontroller and a tableview (I removed its subviews since they're not relevent).
<UIWindow: 0x411fd50; frame = (0 0; 320 480); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x4120af0>>
: <UILayoutContainerView: 0x4123310; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0x411f800>>
: | <UINavigationTransitionView: 0x4123500; frame = (0 0; 320 480); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x41232e0>>
: | : <UIViewControllerWrapperView: 0x4519d30; frame = (0 64; 320 416); autoresize = W+H; layer = <CALayer: 0x4519a40>>
: | : | <UITableView: 0x7808000; frame = (0 0; 320 416); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x45182a0>>
: | <UINavigationBar: 0x45018b0; frame = (0 20; 320 44); clipsToBounds = YES; autoresize = W; layer = <CALayer: 0x4500fe0>>
: | : <UINavigationItemView: 0x4522a20; frame = (100 8; 160 27); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x4526310>>
: | : <UINavigationItemButtonView: 0x45230a0; frame = (5 7; 87 30); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x4520260>>
<_UIAlertOverlayWindow: 0x4179b70; frame = (0 0; 320 480); opaque = NO; layer = <CALayer: 0x4188dc0>>
: <UIAlertView: 0x4194bc0; frame = (3.8 161.95; 312.4 177.1); transform = [1.1, 0, 0, 1.1, 0, 0]; opaque = NO; animations = { transform=<CABasicAnimation: 0x4191160>; opacity=<CABasicAnimation: 0x41226f0>; }; layer = <CALayer: 0x4144c30>>
: | <UILabel: 0x4177e70; frame = (12 15; 260 23); text = 'Name of Date'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x4179370>>
: | <UILabel: 0x418b100; frame = (12 45; 260 41); text = 'Name of the date that you...'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x4128450>>
: | <UIThreePartButton: 0x41942a0; frame = (11 102; 262 43); opaque = NO; tag = 1; layer = <CALayer: 0x4191f30>>
Here is the code that produces the dump. I found it useful on occasion to see what is going on when something isn't doing what I expect:
void dumpView(UIView* aView, NSString* indent) {
if (aView) {
NSLog(#"%#%#", indent, aView); // dump this view
if (aView.subviews.count > 0) {
NSString* subIndent = [[NSString alloc] initWithFormat:#"%#%#",
indent, ([indent length]/2)%2==0 ? #"| " : #": "];
for (UIView* aSubview in aView.subviews) dumpView( aSubview, subIndent );
[subIndent release];
}
}
}
void dumpWindows() {
for (UIWindow* window in [UIApplication sharedApplication].windows) {
dumpView(window, #"dumpView: ");
}
}
The active UIAlertView lives in a separate window (_UIAlertOverlayWindow). Use .windows property to find it.
The whole UI runs in the main thread.
From the problem that you describe with windows and timing, sounds like you should implement alertView:didDismissWithButtonIndex:. You can trigger your followup code from within that method.
EDIT: if that did not work, I'd try doing a delay to execute the FB stuff after a delay when the window is really guaranteed to be gone.