IT TIP

둘 이상의 디테일 뷰 컨트롤러를 푸시 할 때 "DetailViewController의 모양 전환을 시작 / 종료하기위한 불균형 호출"

itqueen 2020. 12. 10. 21:33
반응형

둘 이상의 디테일 뷰 컨트롤러를 푸시 할 때 "DetailViewController의 모양 전환을 시작 / 종료하기위한 불균형 호출"


테이블 뷰를 포함하는 뷰 컨트롤러가 있고 테이블의 항목을 선택할 수 있으며 상세 뷰 컨트롤러를 정식으로 만들 수 있습니다.

테이블의 항목은 연관된 시간 기반 트리거를 가질 수있는 항목을 나타내며, 로컬 알림이 만료 될 때 앱이 포 그라운드에있는 경우 항목에 대한 세부 사항보기가 자동으로 표시됩니다.

두 개의 알림이 동시에 만료되어 뷰가 제대로 표시되지 않고 콘솔 로그에 추가로 나타나는 문제가 있습니다. "NNN에 대한 모양 전환을 시작 / 종료하기위한 불균형 호출"여기서 NNN은 내 상세 뷰 컨트롤러입니다.

테이블 뷰 컨트롤러는 다음과 같이 생성됩니다.

 self.tableViewController = [[TableViewController alloc] initWithNibName:@"TableView" bundle:nil];
 UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.tableViewController];
 self.window.rootViewController = navController;

로컬 알림이 만료되고 didReceiveLocalNotification :이 호출되면 앱은 NSNotifcationCenter postNotificationName :을 사용하고 테이블 뷰 컨트롤러가 수신하는 알림을 브로드 캐스트합니다. 테이블 뷰 컨트롤러가 해당 알림을 수신하면 디테일 뷰 컨트롤러를 생성하고 다음과 같이 스택에 푸시합니다.

[self.navigationController pushViewController:detailViewController animated:YES]; 

뷰 컨트롤러가 스택의 맨 위에 있지 않을 때 다른 뷰 컨트롤러를 푸시하면 문제가 발생할 수 있다고 어딘가에서 읽었습니다. 그래서 테이블 뷰 컨트롤러가 두 번째 알림을 받으면 이것이 문제라고 생각했습니다. 이전에 첫 번째 알림이 도착했을 때 세부 정보보기 컨트롤러를 스택에 푸시했기 때문에 더 이상 탐색 스택의 맨 위에 있지 않습니다.

그래서 푸시 코드를 다음과 같이 변경했습니다.

[[self.navigationController topViewController].navigationController pushViewController:detailController animated:YES];

그러나 그것은 아무런 차이가 없었습니다.

그래서 다음으로 두 번째 뷰 컨트롤러가 푸시되기 전에 첫 번째 디테일 뷰 컨트롤러가 완전히 표시 될 기회가 없기 때문에 문제가있을 수 있다고 생각했습니다. 그래서 앱의 알림 게시를 다음을 사용하여 변경했습니다.

[[NSNotificationCenter defaultCenter] postNotificationName: 

...에

[[NSNotificationQueue defaultQueue] enqueueNotification: postingStyle:NSPostWhenIdle]

따라서 푸시가 앱 루프의 동일한 반복 내에서 발생하지 않도록합니다. 그러나 그것은 차이를 만들지 않았고, 디테일 뷰 컨트롤의 푸시를 지연 시키려고 시도하지도 않았습니다.

double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [[self.navigationController topViewController].navigationController     pushViewController:detailController animated:YES]; 
});

문제가 무엇인지, 다음에 무엇을 시도해야할지 모르겠습니다. 아이디어가 있습니까?


"외모 전환을 시작 / 종료하기위한 불균형 호출"

현재 뷰 컨트롤러가 표시를 완료하기 전에 새 뷰 컨트롤러를 표시하려고 할 때 발생합니다. viewWillAppear에서 탐색하여 재현 할 수 있습니다.

기본적으로 거의 동시에 두 개의 뷰 컨트롤러를 스택에 푸시하려고합니다. 표시해야하는 상세보기 목록을 유지하는 테이블보기 컨트롤러에 큐를 유지하도록 제안합니다. 한 번에 하나씩 스택에 푸시하고 현재 세부 정보보기에서 종료 할 때 표시해야하는 대기중인 세부 정보보기가 있는지 확인합니다.

이러한 종류의 탐색은 사용자에게 혼란을 줄 것입니다. 상세보기가 여러 항목을 지원하도록하는 것이 더 좋습니다.


''의 외모 전환 시작 / 종료를위한 불균형 통화

마지막 관련 애니메이션이 완료되기 전에 애니메이션이 시작됨을 나타냅니다. 그래서, 당신은 새로운 것을 밀기 전에 뷰 컨트롤러를 터 뜨리고 있습니까? 아니면 뿌리를 내릴 수 있습니까? 그렇다면 애니메이션없이 시도해보십시오. 즉,

[self.navigationController popToRootViewControllerAnimated:NO];

그리고 이것이 문제를 해결하는지 확인하십시오. 제 경우에는 이것이 트릭이었습니다.


현재보기 컨트롤러가 표시를 완료하기 전에 새보기 컨트롤러를 표시하려고하면 "불균형 한 호출 시작 / 종료 모양 전환"오류가 발생합니다.

따라서 첫 번째 애니메이션이 완료 될 때까지 새 VC를 제시하지 않도록해야합니다.

didShowViewController 및 willShowViewController를 사용하여 이전 VC가 애니메이션을 완료하기 전에 새 VC 표시를 차단합니다. Animation : YES로 popViewController를 만드는 것은 backButtonAction을위한 것입니다.

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [self.myNavView.backButton addTarget:self action:@selector(backButtonAction) forControlEvents:UIControlEventTouchUpInside];
}

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [self.myNavView.backButton removeTarget:self action:@selector(backButtonAction) forControlEvents:UIControlEventTouchUpInside];
}

스택에서 VC를 두 번 이상 팝하려고 할 때도 발생할 수 있습니다. 제 경우에는 VC를 터뜨린 메서드가 실수로 여러 번 호출되었습니다. 내가 그것을 정리하면 문제가 사라졌습니다.


실제로 푸시 애니메이션이 끝날 때까지 기다려야합니다. 따라서 UINavigationController를 위임하고 애니메이션이 끝날 때까지 밀지 않도록 할 수 있습니다.

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
    waitNavigation = NO;
}


-(void)showGScreen:(id)gvc{

    if (!waitNavigation) {
        waitNavigation = YES;
        [_nav popToRootViewControllerAnimated:NO];
        [_nav pushViewController:gvc animated:YES];
    }
}

In my case, I was implementing a custom container view controller, and I was getting the warning when swapping child view controllers, despite the fact that I was calling both beginAppearanceTransition(_:animated:) and endAppearanceTransition() on both the entering and the exiting view controllers.

I solved it by reordering the method calls for the entering view controller; from:

addChildViewController(newContent)
targetContainer.insertSubview(newContent.view, at: 0)

newContent.beginAppearanceTransition(true, animated: animated)
// Called AFTER adding subview 

to:

// Called BEFORE adding subview 
newContent.beginAppearanceTransition(true, animated: animated)

addChildViewController(newContent)
targetContainer.insertSubview(newContent.view, at: 0)

Hope this helps someone!


Look at these overloads:

If they are empty, then remark them and rebuild.

- (void) beginAppearanceTransition:(BOOL) isAppearing animated:(BOOL)animated {}
- (void) becomeActive:(NSNotification *) notification {}

In my case the problem is that I am presenting a viewController (alert) on an already presented viewController (full screen sheet). UIKit walks up the viewController parent chain but not the presenting chain so there is a mismatch when reaching the presented and the window root view controller. Manually calling beginAppearanceTransition in these cases made the message go away, though is seems rather a patch for a symptom than a real remedy for the error.


You can add a breakpoint to

-[UIViewController _endAppearanceTransition:]

from where UIKit prints

"Unbalanced calls to begin/end appearance transitions for %@."

This can help you with your investigations


Are you using the appearance proxy feature?

I have found very problematic this feature, last time I have a

"Unbalanced calls to begin/end appearance transitions for"

I solved it removing the [[UITextField appearance] ..] methods.

Hope this helps

참고URL : https://stackoverflow.com/questions/9088465/unbalanced-calls-to-begin-end-appearance-transitions-for-detailviewcontroller

반응형