একবারে পদ্ধতি সুইজলিং ব্যবহার করে সমস্ত ইউআইভিউকন্ট্রোলার দৃষ্টান্তগুলিতে আইওএস 13 এ মোডালপ্রেজেন্টেশন স্টাইল পরিবর্তন করুন


11

[প্রশ্নোত্তর] আইওএস 13 এ কি UIViewController.modalPresentationStyleবিশ্বব্যাপী মান পরিবর্তন করা সম্ভব তাই এটি আইওএস 12 (বা এর আগের) এর মতো আচরণ করে?


কেন?

আইওএস 13 SDK এর মধ্যে ডিফল্ট মান UIViewController.modalPresentationStyleসম্পত্তি থেকে পরিবর্তন করা হয়েছে UIModalPresentationFullScreenথেকে UIModalPresentationAutomaticযা, যেমন যতদূর আমি জানি, এর সমাধান UIModalPresentationPageSheetiOS ডিভাইস চালু বা আইফোন উপর অন্তত।

যে প্রকল্পটি আমি বেশ কয়েক বছর ধরে কাজ করে চলেছি তা বেশ বড় হয়ে গেছে, তাই এখানে অনেকগুলি স্থান রয়েছে যেখানে একটি ভিউ কন্ট্রোলার উপস্থাপন করা হয়। নতুন উপস্থাপনা শৈলী সর্বদা আমাদের অ্যাপ্লিকেশন ডিজাইনের সাথে মেলে না এবং কখনও কখনও এটি ইউআই বিচ্ছিন্ন হয়ে যায়। কোনটি কেন, আমরা পরিবর্তন করতে deciced UIViewController.modalPresentationStyleফিরে UIModalPresentationFullScreenহিসাবে এটি ছিল প্রাক iOS13 SDK এর এর সংস্করণ নেই।

তবে নিয়ন্ত্রক উপস্থাপিত প্রতিটি স্থানে viewController.modalPresentationStyle = UIModalPresentationFullScreenকল করার আগে যুক্ত করা presentViewController:animated:completion:ওভারকিলের মতো বলে মনে হয়েছিল। তদ্ব্যতীত, সেই সময় আমাদের মোকাবিলা করার জন্য আরও গুরুতর বিষয় ছিল, সে কারণেই, আপাতত বা কমপক্ষে আমরা আমাদের ডিজাইনগুলি আপডেট না করে এবং সমস্ত ইউআই সংক্রান্ত সমস্যাগুলি সমাধান না করা পর্যন্ত আমরা পদ্ধতি সুইজলিং পদ্ধতির সাথে যাওয়ার সিদ্ধান্ত নিয়েছিলাম।

কার্যনির্বাহী সমাধানটি আমার উত্তরে উপস্থাপন করা হয়েছে, তবে আমি এমন কোনও প্রতিক্রিয়ার প্রশংসা করব যা আমাকে বলছে যে এরকম পদ্ধতির ক্ষয়ক্ষতি বা পরিণতি কী হতে পারে।

উত্তর:


12

পদ্ধতিটি সুইজলিং ব্যবহার করে আমরা এটি কীভাবে অর্জন করেছি তা এখানে রয়েছে:


উদ্দেশ্য গ

UIViewController + + iOS13Fixes.h

#import <Foundation/Foundation.h>

@interface UIViewController (iOS13Fixes)
@end

ইউআইভিউকন্ট্রোলার + আইওএস 13 ফিক্স.এম

#import <objc/runtime.h>

@implementation UIViewController (iOS13Fixes)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];
        SEL originalSelector = @selector(presentViewController:animated:completion:);
        SEL swizzledSelector = @selector(swizzled_presentViewController:animated:completion:);

        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

        BOOL methodExists = !class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));

        if (methodExists) {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        } else {
            class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
        }
    });
}

- (void)swizzled_presentViewController:(nonnull UIViewController *)viewController animated:(BOOL)animated completion:(void (^)())completion {

    if (@available(iOS 13.0, *)) {
        if (viewController.modalPresentationStyle == UIModalPresentationAutomatic || viewController.modalPresentationStyle == UIModalPresentationPageSheet) {
            viewController.modalPresentationStyle = UIModalPresentationFullScreen;
        }
    }

    [self swizzled_presentViewController:viewController animated:animated completion:completion];
}

@end

দ্রুতগতি

UIViewController + + iOS13Fixes.swift

import UIKit

@objc public extension UIViewController {

    private func swizzled_present(_ viewControllerToPresent: UIViewController, animated: Bool, completion: (() -> Void)?) {

        if #available(iOS 13.0, *) {
            if viewControllerToPresent.modalPresentationStyle == .automatic || viewControllerToPresent.modalPresentationStyle == .pageSheet {
                viewControllerToPresent.modalPresentationStyle = .fullScreen
            }
        }

        self.swizzled_present(viewControllerToPresent, animated: animated, completion: completion)
    }

    @nonobjc private static let _swizzlePresentationStyle: Void = {
        let instance: UIViewController = UIViewController()
        let aClass: AnyClass! = object_getClass(instance)

        let originalSelector = #selector(UIViewController.present(_:animated:completion:))
        let swizzledSelector = #selector(UIViewController.swizzled_present(_:animated:completion:))

        let originalMethod = class_getInstanceMethod(aClass, originalSelector)
        let swizzledMethod = class_getInstanceMethod(aClass, swizzledSelector)

        if let originalMethod = originalMethod, let swizzledMethod = swizzledMethod {
            if !class_addMethod(aClass, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)) {
                method_exchangeImplementations(originalMethod, swizzledMethod)
            } else {
                class_replaceMethod(aClass, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
            }
        }
    }()

    @objc static func swizzlePresentationStyle() {
        _ = self._swizzlePresentationStyle
    }
}

এবং এর মধ্যে AppDelegate, application:didFinishLaunchingWithOptions:কল করে (কেবলমাত্র সুইফ্ট সংস্করণ) সুইজলিংয়ের ডাক দিন:

UIViewController.swizzlePresentationStyle()

নিশ্চিত হয়ে নিন যে এটি কেবল একবার বলা হয়েছে (ব্যবহার dispatch_onceবা কিছু সমতুল্য)।


পদ্ধতি এখানে সুইজিং সম্পর্কে আরও:


1
একটি সমস্যা এমন একটি আইপ্যাডে চলবে যেখানে আপনি আসলে কোনও পৃষ্ঠা শীট চান এবং পুরো স্ক্রিনটি নয়। আপনি কেবলমাত্র সম্পূর্ণ পর্দায় স্বয়ংক্রিয়ভাবে পরিবর্তন করতে এবং আপনার উপস্থাপনা ভিউ নিয়ন্ত্রকের কমপ্যাক্ট প্রস্থের বৈশিষ্ট্য উপস্থিত থাকলে তা করতে পারেন only
rmaddy

এই সমাধান কি ভাল? কেউ যদি সত্যিই। পৃষ্ঠাগুলি হিসাবে কোনও ভিউকন্ট্রোলার উপস্থাপন করতে চান তবে কী হবে?
ইব্রাহিমিলাজম

1
@ibrahimyilmaz তারপর আপনার সেট viewController.modalPresentationStyleথেকে .pageSheetএবং কল self.swizzled_present(:,:,:)। সম্ভবত এটি খুব সুন্দর নয়, তবে এই পোস্টের পুরো পয়েন্টটি এই ধারণার উপর ভিত্তি করে তৈরি হয়েছিল যে আপনার কাছে ইতিমধ্যে মডেল উপস্থাপনার জন্য প্রচুর কল সহ একটি বিদ্যমান প্রকল্প রয়েছে এবং আপনি কোডের প্রতিটি লাইন আপডেট না করেই আইওএস 13 প্রাক আচরণ পুনরুদ্ধার করতে চান।
bevoy
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.