কীভাবে সমাধান করবেন: আইওএস 13.0 এ 'কী উইন্ডো' অবমূল্যায়ন করা হয়েছিল


143

আমি ক্লাউড কিটের সাথে কোর ডেটা ব্যবহার করছি এবং তাই অ্যাপ্লিকেশন শুরু করার সময় আইক্লাউড ব্যবহারকারীর স্থিতি পরীক্ষা করতে হবে। সমস্যার ক্ষেত্রে আমি ব্যবহারকারীর সাথে একটি কথোপকথন ইস্যু করতে চাই এবং UIApplication.shared.keyWindow?.rootViewController?.present(...)এখন পর্যন্ত এটি ব্যবহার করে চলেছি।

এক্সকোড 11 বিটা 4-তে এখন একটি নতুন অবমূল্যায়ন বার্তা এসেছে, আমাকে বলছে:

আইওএস ১৩.০-তে 'কী উইন্ডো' অবমূল্যায়ন করা হয়েছিল: একাধিক দৃশ্যের সমর্থনকারী অ্যাপ্লিকেশনগুলির জন্য ব্যবহার করা উচিত নয় কারণ এটি সমস্ত সংযুক্ত দৃশ্যে কী উইন্ডোটি ফেরত দেয়

পরিবর্তে আমি কীভাবে ডায়লগটি উপস্থাপন করব?


আপনি এটা করছেন SceneDelegateবা না AppDelegate? এবং, আপনি কি আরও কিছু কোড পোস্ট করতে পারেন যাতে আমরা সদৃশ করতে পারি?
dfd

4
আইওএস-তে কোনও 'কী উইন্ডো' ধারণা নেই কারণ একক অ্যাপ্লিকেশনটিতে একাধিক উইন্ডোজ থাকতে পারে। আপনি নিজের তৈরি উইন্ডোটি আপনার SceneDelegate(যদি আপনি ব্যবহার করছেন SceneDelegate) সংরক্ষণ করতে পারেন
সুদারা

4
@ সুদারা: সুতরাং, আমার কাছে যদি এখনও কোনও ভিউ কন্ট্রোলার না থাকে তবে আপনি একটি সতর্কতা উপস্থাপন করতে চান - কোনও দৃশ্যের সাথে এটি কীভাবে করবেন? কীভাবে দৃশ্যটি পাবেন, যাতে এর রুটভিউ কনট্রোলারটি পুনরুদ্ধার করা যায়? (সুতরাং, এটি সংক্ষেপে বলার জন্য: ইউআইএপ্লিকেশনটির জন্য "ভাগ করে নেওয়া" এর সমমানের দৃশ্যটি কী?)
হার্ডি

উত্তর:


108

এটি আমার সমাধান:

let keyWindow = UIApplication.shared.connectedScenes
        .filter({$0.activationState == .foregroundActive})
        .map({$0 as? UIWindowScene})
        .compactMap({$0})
        .first?.windows
        .filter({$0.isKeyWindow}).first

ব্যবহার যেমন:

keyWindow?.endEditing(true)

4
ধন্যবাদ - এমন কিছু যা খুঁজে বের করার জন্য খুব স্বজ্ঞাত নয় ... 8-)
হার্ডি

ইতিমধ্যে আমি একাধিক দৃশ্যের নমুনা ( বিকাশকারী / অ্যাপ্লিকেশন / ডকুমেন্টেশন / ইউইকিট / অ্যাপ_অ্যান্ড_এনভায়রনমেন্ট /… ) দিয়ে পদ্ধতির পরীক্ষা করেছি এবং সমস্ত প্রত্যাশার মতো কাজ করেছে।
বার্নি

4
এখানে activationStateমানটির জন্য পরীক্ষা করাও উপযুক্ত হতে পারে foregroundInactive, যদি আমার সতর্কতা উপস্থাপন করা হয় তবে আমার পরীক্ষায় এটি হবে।
ড্রিউ

4
@ অঙ্কিত এটি পরীক্ষা করা উচিত কারণ অ্যাপ্লিকেশন শুরু হওয়ার সাথে সাথে ভিউ কন্ট্রোলার ইতিমধ্যে দৃশ্যমান তবে রাজ্যটি হলforegroundInactive
গারগো

4
এই কোডটি আমার জন্য কী উইন্ডো = শূন্য করে। mattসমাধান এক যে কাজ করে।
হাঁস

213

গ্রহণযোগ্য উত্তর, বুদ্ধিমান থাকাকালীন, অত্যধিক বিস্তৃত হতে পারে। আপনি ঠিক একই ফলাফলটি আরও সহজেই পেতে পারেন:

UIApplication.shared.windows.filter {$0.isKeyWindow}.first

আমি এও সতর্ক করে বলব যে অবমূল্যায়নকে keyWindowঅতিরিক্ত গুরুত্ব সহকারে নেওয়া উচিত নয়। সম্পূর্ণ সতর্কতা বার্তাটি পড়ে:

আইওএস ১৩.০-তে 'কী উইন্ডো' অবমূল্যায়ন করা হয়েছিল: একাধিক দৃশ্যের সমর্থনকারী অ্যাপ্লিকেশনগুলির জন্য ব্যবহার করা উচিত নয় কারণ এটি সমস্ত সংযুক্ত দৃশ্যে কী উইন্ডোটি ফেরত দেয়

সুতরাং আপনি যদি আইপ্যাডে একাধিক উইন্ডোজ সমর্থন না করেন তবে এগিয়ে যাওয়া এবং ব্যবহার চালিয়ে যাওয়াতে কোনও আপত্তি নেই keyWindow


আপনি এই জাতীয় সেগুটি কীভাবে পরিচালনা করবেন let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "homeVC") as! UITabBarController UIApplication.shared.keyWindow?.rootViewController = vcকারণ আইওএস 13 এবং কার্ড ভিউ দিয়ে এটি একটি সমস্যা হয়ে যায় কারণ কোনও ব্যবহারকারী লগ আউট করার পরে ভিউ হায়ারার্কির মূল অ্যাপ্লিকেশনটির সাথে লগইন স্ক্রিনে ঠেলে দেবে যেখানে তারা সোয়াইপ করে এবং যা ফিরে আসতে পারে সমস্যাযুক্ত।
লুকাস বিম্বা

4
@ মারিও এটি উইন্ডোজ অ্যারেতে প্রথম উইন্ডো নয়। এটি উইন্ডোজ অ্যারেতে প্রথম কী উইন্ডো।
ম্যাট

4
@ মারিও তবে প্রশ্নটি অনুমান করে যে এখানে কেবল একটি দৃশ্য আছে। সমস্যার সমাধান হচ্ছে কেবল একটি নির্দিষ্ট সম্পত্তির অবমূল্যায়ন। অবশ্যই আপনার আইপ্যাডে একাধিক উইন্ডো থাকলে জীবন অনেক জটিল! আপনি যদি সত্যিই একাধিক উইন্ডো আইপ্যাড অ্যাপ্লিকেশন লেখার চেষ্টা করছেন তবে আপনার জন্য শুভকামনা।
ম্যাট

4
@ramzesenok অবশ্যই এটি আরও ভাল হতে পারে। তবে এটি ভুল নয়। বিপরীতে, আমি প্রথম পরামর্শ দিয়েছিলাম যে কী উইন্ডোটি এমন একটি উইন্ডোটির জন্য অ্যাপ্লিকেশন জিজ্ঞাসা করার পক্ষে যথেষ্ট হতে পারে, সুতরাং এর অবমূল্যায়ন এড়ানো উচিতkeyWindow সম্পত্তির । অতএব upvotes। আপনি যদি এটি পছন্দ না করেন তবে এটি ডাউনভোট করুন। তবে আমাকে অন্য কারও উত্তরের সাথে মেলে এটি পরিবর্তন করতে বলবেন না; যে, আমি বলেছি, ভুল হবে।
ম্যাট

11
এটি এখন সরল করে দেওয়া যেতে পারেUIApplication.shared.windows.first(where: \.isKeyWindow)
দাদালার

77

ম্যাট এর দুর্দান্ত উত্তরে কিছুটা উন্নতি করা, এটি আরও সহজ, খাটো এবং আরও মার্জিত:

UIApplication.shared.windows.first { $0.isKeyWindow }

4
ধন্যবাদ! উদ্দেশ্যমূলক সি এটি করার কোন উপায় আছে?
অ্যালেনকিটিভি

4
@ অ্যালেনকটিভি দুর্ভাগ্যক্রমে এর NSArrayসমতুল্য নেই first(where:)। আপনি filteredArrayUsingPredicate:এবং এর সাথে একটি ওয়ান-লাইন রচনা করার চেষ্টা করতে পারেন firstObject:
pommy

4
@ অ্যালেন্কটিভি কোড মন্তব্য বিভাগে ম্যাঙ্গেল হয়ে গেছে, তাই আমি নীচে একটি উদ্দেশ্য-সি সমতুল্য পোস্ট করেছি।
ব্যবহারকারী2002649

এক্সকোড ১১.২ সংকলক এই উত্তরের সাথে একটি ত্রুটির কথা জানিয়েছে এবং প্রথম বন্ধনী যুক্ত করার পরামর্শ দিয়েছে এবং এতে লিখিত বিষয়বস্তু রয়েছে first(where:):UIApplication.shared.windows.first(where: { $0.isKeyWindow })
ইয়াসাইন এলবাডাউই

4
এটি এখন UIApplication.shared.windows.first(where: \.isKeyWindow)
সরলীকৃতও

30

এখানে সনাক্তকরণের পিছনের সামঞ্জস্যপূর্ণ উপায় keyWindow:

extension UIWindow {
    static var key: UIWindow? {
        if #available(iOS 13, *) {
            return UIApplication.shared.windows.first { $0.isKeyWindow }
        } else {
            return UIApplication.shared.keyWindow
        }
    }
}

ব্যবহার:

if let keyWindow = UIWindow.key {
    // Do something
}

4
এটি সর্বাধিক মার্জিত উত্তর এবং এটি দেখায় যে সুইফট কী সুন্দর extension। 🙂
ক্লিফটন

4
প্রাপ্যতা চেক, কমই প্রয়োজন যেহেতু windowsএবং isKeyWindowআইওএস 2.0 থেকে প্রায় হয়েছে, এবং first(where:)4 Xcode 9.0 / সুইফট যেহেতু / 2017.
অস্ট্র্রেলিয়া বা নিউজিল্যাণ্ডের ব্রিটিশ অভিবাসী

4
UIApplication.keyWindow: আইওএস 13.0 উপর অবচিত হয়েছে @available (প্রয়োজন iOS, চালু: 2.0, থামানো হয়েছে: 13.0, বার্তা: "যেমন সমস্ত সংযুক্ত লোকচক্ষুর জুড়ে একটি কী জানালা ফেরৎ উচিত অ্যাপ্লিকেশন একাধিক দৃশ্য সমর্থন জন্য ব্যবহার করা যাবে")
ভাদিম Bulavin

20

সাধারণত ব্যবহার

সুইফট 5

UIApplication.shared.windows.filter {$0.isKeyWindow}.first

এছাড়াও - ইউআইভিউউকন্ট্রোলারে:

self.view.window

view.window দৃশ্যের জন্য বর্তমান উইন্ডো

ডাব্লুডাব্লুডিসি 2019: এখানে চিত্র বর্ণনা লিখুন

কী উইন্ডোজ

  • উইন্ডো ম্যানুয়ালি ট্র্যাক করুন

17

একটি উদ্দেশ্য-সি সমাধানের জন্য

+(UIWindow*)keyWindow
{
    UIWindow        *foundWindow = nil;
    NSArray         *windows = [[UIApplication sharedApplication]windows];
    for (UIWindow   *window in windows) {
        if (window.isKeyWindow) {
            foundWindow = window;
            break;
        }
    }
    return foundWindow;
}

nullableশিরোনামের ঘোষণায় যুক্ত করতে ভুলবেন না !
বেন লেগজিও

10

একটি UIApplicationএক্সটেনশন:

extension UIApplication {

    /// The app's key window taking into consideration apps that support multiple scenes.
    var keyWindowInConnectedScenes: UIWindow? {
        return windows.first(where: { $0.isKeyWindow })
    }

}

ব্যবহার:

let myKeyWindow: UIWindow? = UIApplication.shared.keyWindowInConnectedScenes

9

আদর্শভাবে, যেহেতু এটি অবহেলা করা হয়েছে ততক্ষণ আমি আপনাকে উইন্ডোটি সিনডেলিগেটে সংরক্ষণ করার পরামর্শ দিচ্ছি। তবে আপনি যদি অস্থায়ীভাবে কাজ করতে চান তবে আপনি একটি ফিল্টার তৈরি করতে পারেন এবং কী উইন্ডোটি ঠিক এর মতো পুনরুদ্ধার করতে পারেন।

let window = UIApplication.shared.windows.filter {$0.isKeyWindow}.first


4

এটি দিয়ে চেষ্টা করুন:

UIApplication.shared.windows.filter { $0.isKeyWindow }.first?.rootViewController!.present(alert, animated: true, completion: nil)


ধন্যবাদ আশ্চর্যজনক, ধন্যবাদ!
লেবু

4

আপনি যদি কোনও ভিউকন্ট্রোলারে এটি ব্যবহার করতে চান তবে আপনি সহজভাবে ব্যবহার করতে পারেন।

self.view.window

3

একটি উদ্দেশ্য-সি সমাধানের জন্যও

@implementation UIWindow (iOS13)

+ (UIWindow*) keyWindow {
   NSPredicate *isKeyWindow = [NSPredicate predicateWithFormat:@"isKeyWindow == YES"];
   return [[[UIApplication sharedApplication] windows] filteredArrayUsingPredicate:isKeyWindow].firstObject;
}

@end

1
NSSet *connectedScenes = [UIApplication sharedApplication].connectedScenes;
for (UIScene *scene in connectedScenes) {
    if (scene.activationState == UISceneActivationStateForegroundActive && [scene isKindOfClass:[UIWindowScene class]]) {
        UIWindowScene *windowScene = (UIWindowScene *)scene;
        for (UIWindow *window in windowScene.windows) {
            UIViewController *viewController = window.rootViewController;
            // Get the instance of your view controller
            if ([viewController isKindOfClass:[YOUR_VIEW_CONTROLLER class]]) {
                // Your code here...
                break;
            }
        }
    }
}

1
- (UIWindow *)mainWindow {
    NSEnumerator *frontToBackWindows = [UIApplication.sharedApplication.windows reverseObjectEnumerator];
    for (UIWindow *window in frontToBackWindows) {
        BOOL windowOnMainScreen = window.screen == UIScreen.mainScreen;
        BOOL windowIsVisible = !window.hidden && window.alpha > 0;
        BOOL windowLevelSupported = (window.windowLevel >= UIWindowLevelNormal);
        BOOL windowKeyWindow = window.isKeyWindow;
        if(windowOnMainScreen && windowIsVisible && windowLevelSupported && windowKeyWindow) {
            return window;
        }
    }
    return nil;
}

0

আমি একই সমস্যা পূরণ। আমি newWindowএকটি দর্শনের জন্য একটি সংযুক্ত করেছি এবং এটি সেট করেছি এটি [newWindow makeKeyAndVisible]; ব্যবহার শেষ হলে এটি সেট করুন [newWindow resignKeyWindow]; এবং তারপরে সরাসরি মূল কী-উইন্ডোটি দেখানোর চেষ্টা করুন [UIApplication sharedApplication].keyWindow

আইওএস 12 এ সমস্ত কিছু ঠিক আছে তবে আইওএস 13 এ মূল কী-উইন্ডোটি স্বাভাবিক প্রদর্শিত হতে পারে না। এটি একটি পুরো সাদা পর্দা দেখায়।

আমি এই সমস্যাটি এর দ্বারা সমাধান করেছি:

UIWindow *mainWindow = nil;
if ( @available(iOS 13.0, *) ) {
   mainWindow = [UIApplication sharedApplication].windows.firstObject;
   [mainWindow makeKeyWindow];
} else {
    mainWindow = [UIApplication sharedApplication].keyWindow;
}

আশা করি এটা সাহায্য করবে.



0

অনেক বিকাশকারী এই অবমূল্যায়নের প্রতিস্থাপনের উদ্দেশ্য সি কোডের জন্য জিজ্ঞাসা করছেন । কী উইন্ডোটি ব্যবহার করতে আপনি নীচের কোডটি ব্যবহার করতে পারেন।

+(UIWindow*)keyWindow {
    UIWindow        *windowRoot = nil;
    NSArray         *windows = [[UIApplication sharedApplication]windows];
    for (UIWindow   *window in windows) {
        if (window.isKeyWindow) {
            windowRoot = window;
            break;
        }
    }
    return windowRoot;
}

আমি AppDelegateক্লাসে এই পদ্ধতিটি ক্লাসের পদ্ধতি হিসাবে তৈরি এবং যুক্ত করেছি এবং খুব নীচের দিকের সাথে এটি ব্যবহার করি।

[AppDelegate keyWindow];

নীচের মত AppDelegate.h শ্রেণিতে এই পদ্ধতিটি যুক্ত করতে ভুলবেন না।

+(UIWindow*)keyWindow;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.