code

iOS 애플리케이션에서 최상위보기 / 창에 대한 참조 얻기

codestyles 2020. 8. 23. 09:15
반응형

iOS 애플리케이션에서 최상위보기 / 창에 대한 참조 얻기


iOS 애플리케이션에서 알림을 표시하기위한 재사용 가능한 프레임 워크를 만들고 있습니다. UIAlertView와 같이 애플리케이션의 다른 모든 것 위에 알림보기를 추가하고 싶습니다. NSNotification 이벤트를 수신하고 응답으로 뷰를 추가하는 관리자를 초기화 할 때 응용 프로그램의 최상위 뷰에 대한 참조를 가져와야합니다. 이것은 내가 현재 가지고있는 것입니다.

_topView = [[[[UIApplication sharedApplication] keyWindow] subviews] lastObject];

이것은 모든 iOS 응용 프로그램에서 작동합니까 아니면 상위 뷰를 얻는 더 안전하고 더 나은 방법입니까?


일반적으로 상위 뷰를 제공하지만 사용자에게 표시된다는 보장은 없습니다. 예를 들어 화면 밖에 있거나, 알파가 0.0이거나, 크기가 0x0 일 수 있습니다.

keyWindow에 하위보기가 없을 수도 있으므로 먼저 테스트해야합니다. 이것은 드문 일이지만 불가능하지는 않습니다.

UIWindow는 UIView의 하위 클래스이므로 알림이 사용자에게 표시되도록하려면을 사용하여 keyWindow에 직접 추가 addSubview:할 수 있으며 즉시 최상위 뷰가됩니다. 이것이 당신이하려는 일인지 확실하지 않습니다. (귀하의 질문에 따르면 이미 알고있는 것 같습니다.)


다른 모든 것 위에 오버레이를 표시하고 싶을 때마다 응용 프로그램 창 위에 직접 추가합니다.

[[[UIApplication sharedApplication] keyWindow] addSubview:someView]

문제에는 두 부분이 있습니다 : 상단 창, 상단 창 상단보기.

모든 기존 답변이 상단 창 부분을 놓쳤습니다. 그러나 [[UIApplication sharedApplication] keyWindow]상단 창이 보장되지는 않습니다.

  1. 상단 창. windowLevel앱에 대해 동일한 창이 두 개 공존 할 가능성은 거의 없으므로 모든 창을 정렬 windowLevel하여 최상위 창을 가져올 수 있습니다.

    UIWindow *topWindow = [[[UIApplication sharedApplication].windows sortedArrayUsingComparator:^NSComparisonResult(UIWindow *win1, UIWindow *win2) {
        return win1.windowLevel - win2.windowLevel;
    }] lastObject];
    
  2. 상단 창에서 상위 뷰. 완전하게. 질문에서 이미 지적했듯이 :

    UIView *topView = [[topWindow subviews] lastObject];
    

실제로 응용 프로그램에 둘 이상의 UIWindow가있을 수 있습니다. 예를 들어 키보드가 화면에있는 경우 [[UIApplication sharedApplication] windows]최소한 두 개의 창 (키 창 및 키보드 창)이 포함됩니다.

따라서 뷰가 둘 다 위에 나타나도록하려면 다음과 같이해야합니다.

[[[[UIApplication sharedApplication] windows] lastObject] addSubview:view];

(lastObject에 windowLevel 우선 순위가 가장 높은 창이 포함되어 있다고 가정합니다.)


나는 토론이 아니라 제목이 말하는대로 질문을 고수하고있다. 주어진 지점에서 어떤 뷰가 상단에 표시됩니까?

@implementation UIView (Extra)

- (UIView *)findTopMostViewForPoint:(CGPoint)point
{
    for(int i = self.subviews.count - 1; i >= 0; i--)
    {
        UIView *subview = [self.subviews objectAtIndex:i];
        if(!subview.hidden && CGRectContainsPoint(subview.frame, point))
        {
            CGPoint pointConverted = [self convertPoint:point toView:subview];
            return [subview findTopMostViewForPoint:pointConverted];
        }
    }

    return self;
}

- (UIWindow *)topmostWindow
{
    UIWindow *topWindow = [[[UIApplication sharedApplication].windows sortedArrayUsingComparator:^NSComparisonResult(UIWindow *win1, UIWindow *win2) {
        return win1.windowLevel - win2.windowLevel;
    }] lastObject];
    return topWindow;
}

@end

수신기로 모든 UIWindow 또는 수신기로 모든 UIView와 함께 직접 사용할 수 있습니다.


If you are adding a loading view (an activity indicator view for instance), make sure you have an object of UIWindow class. If you show an action sheet just before you show your loading view, the keyWindow will be the UIActionSheet and not UIWindow. And since the action sheet will go away, the loading view will go away with it. Or that's what was causing me problems.

UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
if (![NSStringFromClass([keyWindow class]) isEqualToString:@"UIWindow"]) {
    // find uiwindow in windows
    NSArray *windows = [UIApplication sharedApplication].windows;
    for (UIWindow *window in windows) {
        if ([NSStringFromClass([window class]) isEqualToString:@"UIWindow"]) {
            keyWindow = window;
            break;
        }
    }
}

If your application only works in portrait orientation, this is enough:

[[[UIApplication sharedApplication] keyWindow] addSubview:yourView]

And your view will not be shown over keyboard and status bar.

If you want to get a topmost view that over keyboard or status bar, or you want the topmost view can rotate correctly with devices, please try this framework:

https://github.com/HarrisonXi/TopmostView

It supports iOS7/8/9.


Just use this code if you want to add a view above of everything in the screen.

[[UIApplication sharedApplication].keyWindow addSubView: yourView];

try this

UIWindow *window = [[[UIApplication sharedApplication] windows] lastObject];

참고URL : https://stackoverflow.com/questions/3843411/getting-reference-to-the-top-most-view-window-in-ios-application

반응형