2014-09-29 3 views
0

Я работаю над приложением iOS, которое использует панель вкладок для обмена между подклассами подкласса UISplitViewController. До тех пор, пока семя iOS 8 GM (и версия выпуска) не работало нормально.Приложение сбой в представленииWillAppear UISplitViewController

Однако при построении с iOS 8 SDK для iPad под управлением iOS 8, я постоянно сталкиваюсь с сбоем при переключении на один (и только один) из подкласса контроллера. Этот сбой падает в метод viewWillAppear суперкласса (UISplitViewController), и что-то делать с поповером создается в этом методе:

2014-09-29 09:24:13.526 AppName[51815:2369763] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIPopoverController initWithContentViewController:] must not be called with `nil`.' 
*** First throw call stack: 
(
    0 CoreFoundation      0x0363adf6 __exceptionPreprocess + 182 
    1 libobjc.A.dylib      0x031fda97 objc_exception_throw + 44 
    2 CoreFoundation      0x0363ad1d +[NSException raise:format:] + 141 
    3 UIKit        0x012eaabe -[UIPopoverController _initWithContentViewController:popoverControllerStyle:] + 436 
    4 UIKit        0x0111eb43 -[UISplitViewController _setupHiddenPopoverControllerWithViewController:] + 122 
    5 UIKit        0x0111ed82 -[UISplitViewController _viewControllerHiding:] + 322 
    6 UIKit        0x0112556a -[UISplitViewController viewWillAppear:] + 189 
    7 AppName        0x001ac9c0 -[BaseSplitViewController viewWillAppear:] + 624 
    8 AppName        0x00342b82 -[HomeGlanceController viewWillAppear:] + 306 
    9 UIKit        0x00d7914f -[UIViewController _setViewAppearState:isAnimating:] + 545 
    10 UIKit        0x00d796ca -[UIViewController __viewWillAppear:] + 148 
    11 UIKit        0x00d910b1 -[UIViewController(UIContainerViewControllerProtectedMethods) beginAppearanceTransition:animated:] + 200 
    12 UIKit        0x00dc2dd3 -[UITabBarController transitionFromViewController:toViewController:transition:shouldSetSelected:] + 619 
    13 UIKit        0x00dc2352 -[UITabBarController transitionFromViewController:toViewController:] + 64 
    14 UIKit        0x00dbe545 -[UITabBarController _setSelectedViewController:] + 340 
    15 UIKit        0x00dbe3c7 -[UITabBarController setSelectedViewController:] + 193 
    16 UIKit        0x00dc222b -[UITabBarController _tabBarItemClicked:] + 326 
    17 libobjc.A.dylib      0x032137cd -[NSObject performSelector:withObject:withObject:] + 84 
    18 UIKit        0x00c1f79d -[UIApplication sendAction:to:from:forEvent:] + 99 
    19 UIKit        0x00c1f72f -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 64 
    20 UIKit        0x00f6228d -[UITabBar _sendAction:withEvent:] + 466 
    21 libobjc.A.dylib      0x032137cd -[NSObject performSelector:withObject:withObject:] + 84 
    22 UIKit        0x00c1f79d -[UIApplication sendAction:to:from:forEvent:] + 99 
    23 UIKit        0x00c1f72f -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 64 
    24 UIKit        0x00d52a16 -[UIControl sendAction:to:forEvent:] + 69 
    25 UIKit        0x00d52e33 -[UIControl _sendActionsForEvents:withEvent:] + 598 
    26 UIKit        0x00d52a4e -[UIControl sendActionsForControlEvents:] + 48 
    27 UIKit        0x00f670b1 -[UITabBar(Static) _buttonUp:] + 123 
    28 libobjc.A.dylib      0x032137cd -[NSObject performSelector:withObject:withObject:] + 84 
    29 UIKit        0x00c1f79d -[UIApplication sendAction:to:from:forEvent:] + 99 
    30 UIKit        0x00c1f72f -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 64 
    31 UIKit        0x00d52a16 -[UIControl sendAction:to:forEvent:] + 69 
    32 UIKit        0x00d52e33 -[UIControl _sendActionsForEvents:withEvent:] + 598 
    33 UIKit        0x00d5209d -[UIControl touchesEnded:withEvent:] + 660 
    34 UIKit        0x00c6faba -[UIWindow _sendTouchesForEvent:] + 874 
    35 UIKit        0x00c70595 -[UIWindow sendEvent:] + 791 
    36 AppName        0x004527b4 -[LHCWindow sendEvent:] + 100 
    37 UIKit        0x00c35aa9 -[UIApplication sendEvent:] + 242 
    38 UIKit        0x00c458de _UIApplicationHandleEventFromQueueEvent + 20690 
    39 UIKit        0x00c1a079 _UIApplicationHandleEventQueue + 2206 
    40 CoreFoundation      0x0355e7bf __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15 
    41 CoreFoundation      0x035542cd __CFRunLoopDoSources0 + 253 
    42 CoreFoundation      0x03553828 __CFRunLoopRun + 952 
    43 CoreFoundation      0x035531ab CFRunLoopRunSpecific + 443 
    44 CoreFoundation      0x03552fdb CFRunLoopRunInMode + 123 
    45 GraphicsServices     0x0567524f GSEventRunModal + 192 
    46 GraphicsServices     0x0567508c GSEventRun + 104 
    47 UIKit        0x00c1de16 UIApplicationMain + 1526 
    48 AppName        0x0004c3de main + 222 
    49 libdyld.dylib      0x03b09ac9 start + 1 
) 
libc++abi.dylib: terminating with uncaught exception of type NSException 

Я обнаружил, что ViewController в вопросе имеет три подвидов в первый раз показано, но при удалении любого из двух, которые разделяют фрейм (путем удаления self.view addSubview вызовов) авария еще есть:

UIImageView, {{50, 10}, {260, 490}} 
UIView, {{50, 10}, {260, 490}} 
UIView, {{50, 510}, {670, 390}} 

что бы вызвать поповер связанной аварии в подклассе UISplitViewController?


Это в BaseSplitViewControllerviewWillAppear:. Выполнение контрольной точки исключения останавливается на линии [super viewWillAppear:animated].

- (void)viewWillAppear:(BOOL)animated { 
    iPadAppDelegate *appDelegate_iPad = [Utils getAppDelegateForDeviceType:DEVICE_TYPE_IPAD]; 
    if(![appDelegate_iPad getIsTabInitialised]) { 
     return ; 
    } 
    DDLogVerbose(@"%@ appearing",[self class]); 

    // Which tab is opening? Log it! 
    NSString *screen = [kAnalyticsNavigationPrefix stringByAppendingString:NSStringFromClass([self class])]; 
    [AnalyticsManager logEvent:screen]; 

    // Ensure we don't cover anything with the status bar in iOS 7. It looks like 
    // the orientation code wasn't being called anymore? 
    [self adjustControllerForOrientation:[self interfaceOrientation]]; 

    [super viewWillAppear:animated]; 
} 

BaseSplitViewController init и viewDidLoad - awakeFromNib не перекрываться.

- (id)init { 
    if (self = [super init]) { 
     [self setInterfaceOrientation:[UIApplication sharedApplication].statusBarOrientation]; 

    } 
    return self; 
} 

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 
- (void)viewDidLoad { 
    [super viewDidLoad]; 

    DDLogVerbose(@"%@ loaded",[self class]); 
    isModalViewPresent = NO; 
    self.view.backgroundColor = [UIColor whiteColor]; 

    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) { 
     self.edgesForExtendedLayout = UIRectEdgeNone; 
    } 

} 

HomeGlanceController подклассы BaseSplitViewController (которые подклассы в UISplitViewController). Это единственный подкласс BSVC, который сбой.

- (id)init { 
    if (self = [super init]) { 
     bIsAnyKeypadPresent = FALSE; 
     //to create the favorite zone screen view 
     favoriteScreenBackGroundView = [[UIView alloc] initWithFrame:CGRectMake(280, 0, 720, 430)]; 
     favoriteScreenbackGroundImageView = [[UIImageView alloc] initWithFrame:CGRectMake(40, 5, 667,405)]; 
     favoriteZoneScreenMainView     = [[UIView alloc] initWithFrame:CGRectMake(20, 40 ,640,340)]; 

     favoriteKeypadScreenMainView = [[UIView alloc] initWithFrame:CGRectMake(10, 50 ,200,330)]; 

     // Initialize the layout for the Favorite Controller. 
     [self initFavoriteLayoutCoordinates]; 
     UITabBarItem * tabBarItem = [[UITabBarItem alloc]initWithTitle:HomeGlanceTabTitle 
                   image:[Utils getImageNamed:HomeGlanceIcon] 
                    tag:1]; 
     tabBarItem.selectedImage = [Utils getImageNamed:HomeGlanceSelectedIcon]; 

     self.tabBarItem = tabBarItem; 
     tabBarItem = nil; 

     // pick the co-ordinates of the favorite view from the layout array. 
     if ([favControlCoordinatesArray count]>layoutID) { 
      [self setControllerCoordinates:[favControlCoordinatesArray objectAtIndex:layoutID]]; 
     } 
    } 

    return self; 
} 

- (void) viewDidLoad { 
    // I've tried commenting all but the super call out. The crash remains 
    [self createImageViewForFavorites]; 

    // to create the View for favorite zone 
    [self createBackGroundViewForFavoriteZoneScreen]; 
    [self createFavoriteZoneScreenToolbar]; 
    [self createFavoriteZoneScreenMainView]; 
    [self createFavoriteKeypadScreenToolbar]; 

    [super viewDidLoad]; 
} 

- (void)viewWillAppear : (BOOL) animated { 
    [super viewWillAppear:animated]; 

    [self startTimer]; 
    iPadAppDelegate *appDelegate_iPad = [Utils getAppDelegateForDeviceType:DEVICE_TYPE_IPAD]; 
    if(![appDelegate_iPad getIsTabInitialised]) 
    { 
     return; 
    } 
    [self createFavoriteZoneScreenMainView]; 

    [self createFavoriteKeypadScreenMainView]; 

    // Snipped methods that don't impact the UI directly (commented out in this build) 
} 

По-видимому, происходит сбой только тогда, когда IPAD находится в (или превратились в) режим портрета:

  • Вкладка может быть выбран без сбоев в альбомной ориентации, но вращая к портрету в то время как на эта вкладка выйдет из строя на super willRotateToInterfaceOrientation:duration:.
  • Если выбрана вкладка в то время как в портретном, приложение будет врезаться на super viewWillAppear:

Конечным причина, кажется, то же самое ([UIPopoverController initWithContentViewController:] не должен вызываться с nil.).

+0

Post код, который вызывает это ('BaseSplitViewController' в' - (Недействительными) viewWillAppear' я полагаю) ,Кроме того, чтобы лучше отлаживать ваши исключения, вы можете добавить контрольные точки исключения Objective-C [как описано здесь] (http://stackoverflow.com/questions/26104081/app-crashes-in-viewwillappear-of-uisplitviewcontroller). Это позволит вам узнать точную строку, которая вызывает крушение. –

+0

@ RicardoSánchez-Sáez Добавил этот метод, хотя я не видел ничего, что казалось непосредственно актуальным. И я работал с моей контрольной точкой исключения, она терпит неудачу на 'super viewWillAppear:' call - забыл упомянуть об этом, спасибо, что напомнил мне. – thegrinner

+0

Можете ли вы попробовать перенести вызов '[super viewWillAppear: анимированный '' в первую строку во всех ваших методах 'viewWillAppear'? –

ответ

4

Он появляется по умолчанию preferredDisplayMode является UISplitViewControllerDisplayModeAutomatic и UISplitViewController делает что-то с участием создания контроллера поповера в портрете, когда он имеет этот режим отображения и он вызывает viewWillAppear или вращаются.

Чтобы избежать аварии, я добавил код для изменения режима отображения в методе viewDidLoad:

[self setPreferredDisplayMode:UISplitViewControllerDisplayModeAllVisible]; 
Смежные вопросы