সিএনকন্ট্যাক্টভিউ কনট্রোলারের আইওএস 13.1 এ কীবোর্ড ওভারলেয়িং অ্যাকশন শীট


12

এটি আইওএস 13.1-এর সাথে সুনির্দিষ্ট বলে মনে হচ্ছে, কারণ এটি সিএন কনট্যাকটভিউ কনট্রোলারের একটি পরিচিতি যুক্ত করতে আইওএস 13.0 এবং পূর্ববর্তী সংস্করণগুলিতে প্রত্যাশার মতো কাজ করে, যদি আমি 'বাতিল' করি, ক্রিয়া শিটটি কীবোর্ডের মাধ্যমে ওভারল্যাপিং হচ্ছে। কোনও ক্রিয়া সম্পাদন হচ্ছে না এবং কীবোর্ড খারিজ হচ্ছে না।

উত্তর:


5

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

আমার প্রয়োজন ছিল আমার CNContactViewControllerDelegate contactViewController(_:didCompleteWith:)কাছে বাতিল (যেমন করা হয়েছে) তে ডাকা হবে।

এছাড়াও আমার কোডটি তেমন ছিল না UIViewControllerতাই নেইself.navigationController

যখন আমি এটির সাহায্য করতে পারি তখন জোর আন-র্যাপ ব্যবহার করাও পছন্দ করি না। অতীতে আমাকে কামড়ে ধরেছে তাই আমি if letসেটআপে শৃঙ্খলাবদ্ধ

আমি যা করেছি তা এখানে:

  1. সেখানে CNContactViewControllerসুইজল ফাংশনটি প্রসারিত করুন এবং রাখুন

  2. পাঁচমিশালী মদ্যবিশেষ ফাংশনে আমার ক্ষেত্রে শুধু কল
    CNContactViewControllerDelegateপ্রতিনিধি
    contactViewController(_:didCompleteWith:)সঙ্গে selfএবং
    self.contactযোগাযোগ নিয়ামক থেকে অবজেক্ট

  3. সেটআপ কোডে, সুইজেলমেথোদ কলটি ক্লাসের পরিবর্তে class_getInstanceMethodনির্দিষ্ট করার জন্য নিশ্চিত করুন to CNContactViewControllerself

এবং সুইফট কোড:

class MyClass: CNContactViewControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.changeImplementation()
    }

    func changeCancelImplementation() {

        let originalSelector = Selector(("editCancel:"))
        let swizzledSelector = #selector(CNContactViewController.cancelHack)

        if let originalMethod = class_getInstanceMethod(object_getClass(CNContactViewController()), originalSelector),
           let swizzledMethod = class_getInstanceMethod(object_getClass(CNContactViewController()), swizzledSelector) {

            method_exchangeImplementations(originalMethod, swizzledMethod)
        }
    }

   func contactViewController(_ viewController: CNContactViewController, didCompleteWith contact: CNContact?) {
       // dismiss the contacts controller as usual
       viewController.dismiss(animated: true, completion: nil)
       // do other stuff when your contact is canceled or saved
       ...
    }
}

extension CNContactViewController {
    @objc func cancelHack()  {
        self.delegate?.contactViewController?(self, didCompleteWith: self.contact)
    }
}

কীবোর্ডটি এখনও মুহূর্তের জন্য দেখায় তবে যোগাযোগগুলি নিয়ন্ত্রককে বরখাস্ত করার পরে drops
আশা করি অ্যাপল এটি ঠিক করে দেয়


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

@ জিএক্সোকটি - ফোর্স urwraps এ সম্মত। এবং এগুলি সর্বদা ভয়ঙ্কর হয় না তবে অন্যরাও আপনার মতো হয় না এবং ঝুঁকি উপলব্ধি না করে সর্বদা এগুলি ব্যবহার করতে পারে;)। এর বদলে যদি আমার পছন্দ হয়! যখন আমি 100% নিশ্চিত নই তবে এটি শূন্য হবে না। সেলফ্রন্ট কনট্যাক্ট সম্পর্কে - এর সত্য আমি জানি না যে অ্যাপলের লাইব কোডটি সাধারণত অভ্যন্তরীণভাবে প্রতিনিধিদের কাছে যায় তবে সেলফ্রন্টের যোগাযোগের ডেটা ছিল এবং সিএন কনট্যাক্টভিউ কনট্রোলার ডকটি বলেছে এটি "যোগাযোগটি প্রদর্শিত হচ্ছে" তাই এটি ব্যবহার করা ঠিক বলে মনে হয়েছিল। আমার কোডটি আসলে সমাপ্তির প্রতিনিধিটিতে পাস করা যোগাযোগটি ব্যবহার করে না যাতে আমি কেবল এক্সটেনশনে শূন্য করতে পারি।
ব্যারেট 18

সিএন কনট্যাকটভিউ কনট্রোলারের লিখিত সামগ্রীগুলি (সহ পাঠ্য দর্শন এবং কীবোর্ডগুলি) আলাদা প্রক্রিয়াতে হওয়া উচিত। আপনি যদি এই ভিউ কন্ট্রোলারের জন্য এক্সকোডে 'হায়ারার্কি দেখুন' ব্যবহার করতে পারেন তবে দেখতে পাবেন যে সামগ্রীগুলি দেখা যায় না। ফলস্বরূপ, আমরা কীবোর্ড বা পাঠ্য দর্শনটি নিয়ন্ত্রণ করতে পারি না।
ওয়াইল্ডটিক্স

5

আমি কীবোর্ড খারিজ করার উপায় খুঁজে পাইনি। তবে কমপক্ষে আপনি আমার পদ্ধতিটি ব্যবহার করে ভিউকন্ট্রোলার পপ করতে পারেন।

  1. কেন জানি না তবে CNContactViewController এ কীবোর্ড খারিজ করা অসম্ভব। আমি এডিটিংয়ের চেষ্টা করেছি:, নতুন ইউআইটিেক্সটফিল্ড ফার্স্ট রেসপন্ডার এবং আরও কিছু তৈরি করুন। কিছুই কাজ হয়নি।
  2. আমি "বাতিল" বোতামের জন্য ক্রিয়া পরিবর্তন করার চেষ্টা করেছি। আপনি নেভিগেশনকন্ট্রোলার স্ট্যাকটিতে এই বোতামটি খুঁজে পেতে পারেন, তবে আপনি যখনই কিছু টাইপ করেন ততবার এই ক্রিয়াটি পরিবর্তন করা হয়।
  3. অবশেষে আমি পদ্ধতি সুইজলিং ব্যবহার করেছি। আমি পূর্বে উল্লিখিত হিসাবে কীবোর্ড খারিজ করার কোনও উপায় খুঁজে পাইনি, তবে "বাতিল" বোতাম টিপলে আপনি কমপক্ষে সিএন কনট্যাক্টভিউ কনট্রোলারকে বরখাস্ত করতে পারেন।
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        changeImplementation()
    }

    @IBAction func userPressedButton(_ sender: Any) {
        let controller = CNContactViewController(forNewContact: nil)
        controller.delegate = self
        navigationController?.pushViewController(controller, animated: true)
    }

    @objc func popController() {
        self.navigationController?.popViewController(animated: true)
    }

    func changeImplementation() {
        let originalSelector = Selector("editCancel:")
        let swizzledSelector = #selector(self.popController)

        if let originalMethod = class_getInstanceMethod(object_getClass(CNContactViewController()), originalSelector),
            let swizzledMethod = class_getInstanceMethod(object_getClass(CNContactViewController()), swizzledSelector) {

            method_exchangeImplementations(originalMethod, swizzledMethod)
        }
    }
}

PS: আপনি reddit বিষয়ে অতিরিক্ত তথ্য সন্ধান করতে পারবেন: https://www.reddit.com/r/swift/comments/dc9n3a/bug_with_cnviewcontroller_ios_131/


2

ব্যবহারকারী কীবোর্ডটি খারিজ করতে আসলে সোয়াইপ করতে পারেন এবং তারপরে বাতিল চাপুন এবং অ্যাকশনশিটটি দেখুন। সুতরাং এই সমস্যাটি আফসোসযোগ্য এবং স্পষ্টতই একটি বাগ (এবং আমি একটি বাগ রিপোর্ট দায়ের করেছি) তবে মারাত্মক নয় (তবে এটি নিশ্চিত করার জন্য, ব্যবহারকারীর আবিষ্কারের জন্য কাজটি তুচ্ছ নয়)।

এখানে চিত্র বর্ণনা লিখুন


আপনি যে ফাইলটি প্রতিবেদন করেছেন সেটির সাথে আপনি লিঙ্ক করতে পারবেন?
পাস্কে

1

আইওএস এ স্থির 13.4 এক্সকোড সিমুলেটারে পরীক্ষিত


1

আশেপাশে তাঁর দুর্দান্ত কাজের জন্য @ জিক্সোকটকে ধন্যবাদ আমি মনে করি যারা এটি কাজ করছেন তাদের জন্য এটি খুব দরকারী প্রশ্ন ও পোস্ট CNContactViewController। আমারও এই সমস্যা ছিল (এখন অবধি) তবে উদ্দেশ্য গ। আমি উপরের সুইফট কোডটিকে উদ্দেশ্যমূলক গ্যে ব্যাখ্যা করি।

- (void)viewDidLoad {
    [super viewDidLoad];
    Class class = [CNContactViewController class];

    SEL originalSelector = @selector(editCancel:);
    SEL swizzledSelector = @selector(dismiss); // we will gonna access this method & redirect the delegate via this method

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

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

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

CNContactViewControllerবরখাস্ত অ্যাক্সেসের জন্য একটি বিভাগ তৈরি করা ;

@implementation CNContactViewController (Test)

- (void) dismiss{
    [self.delegate contactViewController:self didCompleteWithContact:self.contact];
}

@end

ছেলেরা যারা সুইজলিংয়ের সাথে তেমন পরিচিত নয় আপনি ম্যাট দ্বারা এই পোস্টটি চেষ্টা করতে পারেন


0

ধন্যবাদ, আপনার কাজের জন্য @GxocT, তবে, এখানে পোস্ট করা সমাধানটি আপনি রেডডিতে পোস্ট করেছেন তার চেয়ে আলাদা।

রেডডিতে থাকা ব্যক্তিটি আমার পক্ষে কাজ করে, আমি এখানে এটি পুনরায় পোস্ট করতে চাই না। পার্থক্যটি সুইজলেড ম্যাথোডের সাথে লাইনে রয়েছে যা হওয়া উচিত:

   let swizzledMethod = class_getInstanceMethod(object_getClass(self), swizzledSelector) {

পুরো আপডেট হওয়া কোডটি হ'ল:

class MyClass: CNContactViewControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.changeImplementation()
    }

    func changeCancelImplementation() {

        let originalSelector = Selector(("editCancel:"))
        let swizzledSelector = #selector(CNContactViewController.cancelHack)

        if let originalMethod = class_getInstanceMethod(object_getClass(CNContactViewController()), originalSelector),
           let swizzledMethod = class_getInstanceMethod(object_getClass(self), swizzledSelector) {

            method_exchangeImplementations(originalMethod, swizzledMethod)
        }
    }

   func contactViewController(_ viewController: CNContactViewController, didCompleteWith contact: CNContact?) {
       // dismiss the contacts controller as usual
       viewController.dismiss(animated: true, completion: nil)
       // do other stuff when your contact is canceled or saved
       ...
    }
}

extension CNContactViewController {
    @objc func cancelHack()  {
        self.delegate?.contactViewController?(self, didCompleteWith: self.contact)
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.