iOS8 में कीबोर्ड की ऊंचाई का सही मूल्य नहीं मिल सकता है


83

मैं इस कोड का उपयोग यह निर्धारित करने के लिए कर रहा था कि कीबोर्ड का आकार क्या है:

- (void)keyboardWillChange:(NSNotification *)notification {
    NSDictionary* keyboardInfo = [notification userInfo];
    NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey];
    CGRect keyboardFrameBeginRect = [keyboardFrameBegin CGRectValue];

}

मैं इसे सिम्युलेटर में चला रहा हूं।

समस्या आईओएस 8 के बाद से है, यह सही मूल्य नहीं देगा, अगर कीबोर्ड के सुझाव ऊपर हैं या यदि मैं उन्हें धक्का देता हूं तो मुझे अलग-अलग (सही नहीं) मान मिलते हैं।

मैं कीबोर्ड सुझावों सहित कीबोर्ड का सटीक आकार कैसे प्राप्त कर सकता हूं?


यदि आप keyboardFrameBeginRectस्थानीय निर्देशांक में परिवर्तित करते हैं तो यह मदद कर सकता है ।
रामप्यारी

@ यह वास्तव में कोई फर्क नहीं पड़ता, मुझे केवल ऊंचाई की आवश्यकता है।
एली ब्रिगिंस्की

जो कि अभिविन्यास के आधार पर गलत हो सकता है। हालाँकि यह अब iOS 8 के तहत एक मुद्दा नहीं हो सकता है। हालांकि इसे आज़माएं और देखें कि क्या इससे कोई फर्क पड़ता है।
रामप्यारी

@rmaddy मैंने इसकी कोशिश की, लेकिन दुख की बात यह है कि यह मदद नहीं की
एली Braginskiy

जवाबों:


98

उपयोग

NSValue* keyboardFrameBegin = [keyboardInfo valueForKey:UIKeyboardFrameEndUserInfoKey];

बहुत बढ़िया जवाब। धन्यवाद। आपको यह कैसे पता चला कि आपको उस कुंजी का उपयोग करना चाहिए? @souvickcse
जूलियन ओसोरियो

6
CGRect keyboardFrame = [कीबोर्डफ़्रेमबेगिन CGRectValue];
Awesomeness

12
मेरे लिए काम नहीं किया, कीबोर्ड अभी भी 258 था, बहुत ऊंचा
23

Thank you @trycatchfinally
souvickcse

1
आज एक सबक सीखा। UIKeyboardFrameEndUserInfoKey और UIKeyboardFrameBeginUserInfoKey में बड़ा अंतर है। धन्यवाद @souvickcse
jejernig

120

IOS में कस्टम कीबोर्ड की शुरुआत के साथ, यह समस्या एक अधिक जटिल हो जाती है।

संक्षेप में, कस्टम कीबोर्ड कार्यान्वयन द्वारा UIKeyboardWillShowNotification को कई बार कॉल किया जा सकता है:

  1. जब Apple सिस्टम कीबोर्ड खोला जाता है (पोर्ट्रेट में)
    • UIKeyboardWillShowNotification 224 की कीबोर्ड ऊंचाई के साथ भेजा गया है
  2. जब स्वेप कीबोर्ड खोला जाता है (पोर्ट्रेट में):
    • UIKeyboardWillShowNotification 0 की कीबोर्ड ऊंचाई के साथ भेजा गया है
    • UIKeyboardWillShowNotification 216 की कीबोर्ड ऊंचाई के साथ भेजा गया है
    • UIKeyboardWillShowNotification 256 की कीबोर्ड ऊंचाई के साथ भेजा गया है
  3. जब SwiftKey कीबोर्ड खोला जाता है (पोर्ट्रेट में):
    • UIKeyboardWillShowNotification 0 की कीबोर्ड ऊंचाई के साथ भेजा गया है
    • UIKeyboardWillShowNotification 216 की कीबोर्ड ऊंचाई के साथ भेजा गया है
    • UIKeyboardWillShowNotification 259 की कीबोर्ड ऊंचाई के साथ भेजा गया है

इन परिदृश्यों को एक कोड-लाइन में ठीक से संभालने के लिए, आपको निम्न करने की आवश्यकता है:

UIKeyboardWillShowNotification और UIKeyboardWillHideNotification नोटिफिकेशन के खिलाफ पर्यवेक्षकों को पंजीकृत करें :

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillShow:)
                                             name:UIKeyboardWillShowNotification
                                           object:nil];    
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWillHide:)
                                             name:UIKeyboardWillHideNotification
                                           object:nil];

वर्तमान कीबोर्ड ऊंचाई को ट्रैक करने के लिए एक वैश्विक चर बनाएँ:

CGFloat _currentKeyboardHeight = 0.0f;

कीबोर्ड ऊंचाई में वर्तमान परिवर्तन पर प्रतिक्रिया करने के लिए keyboardWillShow को लागू करें :

- (void)keyboardWillShow:(NSNotification*)notification {
   NSDictionary *info = [notification userInfo];
   CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
   CGFloat deltaHeight = kbSize.height - _currentKeyboardHeight; 
   // Write code to adjust views accordingly using deltaHeight
   _currentKeyboardHeight = kbSize.height;
}

नोट: आप विचारों की ऑफसेटिंग को चेतन करना चाह सकते हैं। जानकारी शब्दकोश से keyed कोई मान UIKeyboardAnimationDurationUserInfoKey । यह मान उसी गति से आपके परिवर्तनों को प्रदर्शित करने के लिए उपयोग किया जा सकता है जब कीबोर्ड प्रदर्शित किया जा रहा है।

लागू keyboardWillHide रीसेट _currentKeyboardHeight करने और कीबोर्ड खारिज कर दिए जाने पर प्रतिक्रिया:

- (void)keyboardWillHide:(NSNotification*)notification {
   NSDictionary *info = [notification userInfo];
   CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
   // Write code to adjust views accordingly using kbSize.height
   _currentKeyboardHeight = 0.0f;
}

डगंगस्टा, आपका शोध दिलचस्प है, लेकिन सवाल से समस्या यह है कि फ्रेमएंड के गुणों के बजाय फ़्रेमबिजिन प्राप्त करना है। आपके जवाब के अनुसार, क्या आपने डेल्टास के बजाय व्यू एनिमेशन विधि के लिए UIViewAnimationOptionBeginFromCurrentState ध्वज का उपयोग करने पर विचार किया था?
मिकआर

SwiftKey (v 1.2.3) की ऊंचाई के लिए 259 के बजाय, मुझे iOS8.1.3 के साथ iPhone6 ​​+ में 271 मिला।
हेमांग

2
यह अभी भी एक काम कर समाधान है? SwiftKey का उपयोग करते समय मुझे 259 के बजाय 44 की ऊँचाई मिलती है।
किड्डे

क्रेजी, इससे मुझे मदद मिली, लेकिन मुझे कीबोर्ड की ऊंचाई की आवश्यकता थी क्योंकि यह पहले से ही दिखा रहा था, इसलिए मैं कीबोर्डडायशो का निरीक्षण करता हूं: इसके बजाय। Apple के सिर्फ एक ट्रिगर के दौरान ये कस्टम कीबोर्ड 3 सूचनाओं को ट्रिगर क्यों करते हैं? असंगत लगता है।
लिरोन याहदव

यदि आप आईफ़ोन जैसे लैंडस्केप मोड में समस्याएँ हैं जैसे मैं था, तो यह है क्योंकि फ़्रेम END कुंजी में गलत मूल (कम से कम सामान्य iOS 10 कीबोर्ड के लिए) है। KEYBOARD BEGIN RECT: (0.0, 375.0, 667.0, 162.0) ... KEYBOARD END RECT: (0.0, 213.0, 667.0, 162.0)
xaphod

18

जब तक मैं इस StackOverflow लेख में आया, तब तक मेरे पास भी यह मुद्दा था :

UIKeyboardFrameEndUserInfoKey कनवर्ट करें

यह आपको convertRectकीबोर्ड के आकार को उपयोग करने योग्य बनाने के लिए फ़ंक्शन का उपयोग करने के लिए दिखाता है , लेकिन स्क्रीन ओरिएंटेशन पर।

NSDictionary* d = [notification userInfo];
CGRect r = [d[UIKeyboardFrameEndUserInfoKey] CGRectValue];
r = [myView convertRect:r fromView:nil];

पहले, मेरे पास एक आईपैड ऐप था जो इस्तेमाल UIKeyboardFrameEndUserInfoKeyनहीं करता थाconvertRect , लेकिन इसका उपयोग नहीं किया गया था , और यह ठीक काम करता था।

लेकिन iOS 8 के साथ, यह अब ठीक से काम नहीं करता है। अचानक, यह रिपोर्ट करेगा कि लैंडस्केप मोड में iPad पर चलने वाला मेरा कीबोर्ड 1024 पिक्सेल ऊंचा था

तो अब, iOS 8 के साथ, यह आवश्यक है कि आप इस convertRectफ़ंक्शन का उपयोग करें ।


प्री- iOS8 कीबोर्ड की परत हमेशा पोर्ट्रेट ओरिएंटेड स्क्रीन के निर्देशांक में थी। जब मैंने लैंडस्केप मोड में मैन्युअल रूप से ऊंचाई और चौड़ाई को स्वैप करने के लिए कोड जोड़ा था, लेकिन यह iOS 8 पर टूट गया। जहां कीबोर्ड रेक्ट ओरिएंटेशन ओरिएंटेशन से मेल खाता है। ConvertRect समाधान iOS 7 या iOS 8.
user1055568

7

स्विफ्ट 2.0 में लिखे गए डंगस्टास्ट के समाधान के समान :

override func viewDidLoad() {
    super.viewDidLoad()
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil)
}

deinit {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

func keyboardWillShow(notification: NSNotification) {
    guard let kbSizeValue = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else { return }
    guard let kbDurationNumber = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber else { return }
    animateToKeyboardHeight(kbSizeValue.CGRectValue().height, duration: kbDurationNumber.doubleValue)
}

func keyboardWillHide(notification: NSNotification) {
    guard let kbDurationNumber = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber else { return }
    animateToKeyboardHeight(0, duration: kbDurationNumber.doubleValue)
}

func animateToKeyboardHeight(kbHeight: CGFloat, duration: Double) {
    // your custom code here
}

समस्या जब आप क्विक टाइप दिखाते / छिपाते हैं, और स्माइली भी
user3722523

यह चटनी थी। 2.3 स्विफ्ट में मामूली अंतर है, लेकिन यह संकलक से एक स्वत: पूर्ण सुझाव है इसलिए कोई संभावना नहीं है।
एथन पार्कर

5

मैं के लिए बनाते extensionहैंUIViewController

extension UIViewController {
    func keyboardWillChangeFrameNotification(notification: NSNotification, scrollBottomConstant: NSLayoutConstraint) {
        let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber
        let curve = notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber
        let keyboardBeginFrame = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as! NSValue).CGRectValue()
        let keyboardEndFrame = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue()

        let screenHeight = UIScreen.mainScreen().bounds.height
        let isBeginOrEnd = keyboardBeginFrame.origin.y == screenHeight || keyboardEndFrame.origin.y == screenHeight
        let heightOffset = keyboardBeginFrame.origin.y - keyboardEndFrame.origin.y - (isBeginOrEnd ? bottomLayoutGuide.length : 0)

        UIView.animateWithDuration(duration.doubleValue,
            delay: 0,
            options: UIViewAnimationOptions(rawValue: UInt(curve.integerValue << 16)),
            animations: { () in
                scrollBottomConstant.constant = scrollBottomConstant.constant + heightOffset
                self.view.layoutIfNeeded()
            },
            completion: nil
        )
    }
}

आप इस तरह का उपयोग कर सकते हैं:

override func viewDidLoad() {
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillChangeFrameNotification:", name: UIKeyboardWillChangeFrameNotification, object: nil)
}

...

deinit {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

func keyboardWillChangeFrameNotification(notification: NSNotification) {
    self.keyboardWillChangeFrameNotification(notification, scrollBottomConstant: inputContainerBottom)
    // Write more to here if you want.
}

वानबोक चोई, किन विचारों का उपयोग किया जा रहा है inputContainerBottom?
नथानिएल ब्लमर

@Nathaniel UITextField या UITextView के निचले स्थान से नीचे की ओर बाधाएं। ;) मैंने इसे अपनी परियोजना पर संपादित किया था। मैं इसे
रीपोस्ट करूंगा

4

ऐसे समय होते हैं जब देवों को वास्तव में दिखाए जाने से पहले कीबोर्ड की ऊंचाई जानने की आवश्यकता होती है, जिससे उन्हें इंटरफ़ेस को उचित रूप से पूर्व-लेआउट की अनुमति मिलती है।

अगर ऐसा है, तो यहाँ एक समावेशी युक्ति है:

यहाँ छवि विवरण दर्ज करें

इसमें शीर्ष पर त्वरित प्रकार की पट्टी शामिल है, क्योंकि यह iOS के सभी वर्तमान संस्करणों में डिफ़ॉल्ट रूप से है।

यहाँ स्विफ्ट 3 नोटिफिकेशन सेटअप है जिसका उपयोग मैंने इस परीक्षण के लिए किया था, अगर किसी को इसकी आवश्यकता हो तो:

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: .UIKeyboardWillShow, object: nil)
}

func keyboardWillShow(notification: NSNotification) {
    guard let keyboardSize = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else { return }
    print("\(keyboardSize)")
}

1

स्विफ्ट के लिए केवल एक तार:

let keyboardSize = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue().size

UIKeyboardFrameEndUserInfoKeyहमेशा स्टोर करता है NSValue, इसलिए इसे जांचने की कोई आवश्यकता नहीं है।


0

मैंने डिफॉल्ट कीबोर्ड और एक कस्टम ( UIPickerView) कीबोर्ड के बीच स्विच करते समय एक मुद्दे को देखा - कस्टम कीबोर्ड डिफ़ॉल्ट कीबोर्ड से स्विच करने के बाद 162 के बजाय 253 की ऊंचाई दिखाएगा।

इस मामले में जो काम किया गया autocorrectionType = UITextAutocorrectionTypeNo;वह कस्टम कीबोर्ड के साथ इनपुट फ़ील्ड के लिए सेट किया गया था ।

केवल iOS 8 में समस्या (सिम्युलेटर पर परीक्षण)। यह iOS 9 (सिम्युलेटर या डिवाइस) में नहीं होता है।


0

स्विफ्ट में, एक लाइन में नहीं ...

self.keyboardDidShowObserver = NSNotificationCenter.defaultCenter().addObserverForName(UIKeyboardDidShowNotification, object: nil, queue: NSOperationQueue.mainQueue(), usingBlock: { (notification) in
        if let userInfo = notification.userInfo, let keyboardFrameValue = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue {
            let keyboardRect = keyboardFrameValue.CGRectValue()
            // keyboardRect.height gives the height of the keyboard
            // your additional code here...
        }
    })

0
[notificationCenter addObserverForName:UIKeyboardWillChangeFrameNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification * _Nonnull note) {

    float keyboardHeight = [[note.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;

}];
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.