เลื่อนมุมมองด้วยแป้นพิมพ์โดยใช้ Swift


278

ฉันมีแอพที่มีช่องข้อความอยู่ครึ่งล่างของมุมมอง ซึ่งหมายความว่าเมื่อฉันไปพิมพ์ในฟิลด์ข้อความแป้นพิมพ์จะครอบคลุมฟิลด์ข้อความ

ฉันจะเลื่อนมุมมองขึ้นไปข้างบนขณะพิมพ์ได้อย่างไรเพื่อดูว่าฉันกำลังพิมพ์อะไรแล้วเลื่อนกลับไปที่ตำแหน่งเดิมเมื่อคีย์บอร์ดหายไป

ฉันดูทุกที่ แต่โซลูชั่นทั้งหมดดูเหมือนจะอยู่ใน Obj-C ซึ่งฉันยังไม่สามารถแปลงได้

ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชมอย่างมาก.


วิธีที่ดีที่สุดในการทำเช่นนี้คือการวางเนื้อหาของคุณไว้ในUIScrollViewจากนั้นปรับคุณสมบัติcontentInsetของมุมมองเลื่อนตามความสูงของคีย์บอร์ดเมื่อแสดง ไม่ยอมรับความสูงของแป้นพิมพ์อย่างแน่นอน - ใช้ค่าจากการแจ้งเตือน "แป้นพิมพ์จะแสดง"
nielsbot

1
อันที่จริงเอกสารของ Apple บอกให้คุณทราบถึงวิธีการทำเช่นนี้ภายใต้ "การจัดการแป้นพิมพ์": developer.apple.com/library/ios/documentation/StringsTextFonts/
nielsbot

11
ฉันคิดว่าคำตอบทั้งหมดด้านล่างไม่ได้คำนึงถึงกรณีใดกรณีหนึ่ง: ถ้าคุณมีหลายฟิลด์ข้อความและบางคำอยู่ด้านบนของหน้าจอ ผู้ใช้ทุกที่ทุกเวลาก๊อกฟิลด์ข้อความนั้นก็ขึ้นไปเกินหน้าจอผมค่อนข้างมั่นใจว่าคำตอบที่ถูกต้องควรตรวจสอบว่าit is actually needed to scroll view up when keyboard appears
theDC

คำตอบนี้สามารถตรวจพบว่าจำเป็นต้องเลื่อนดูเมื่อแป้นพิมพ์ปรากฏขึ้นหรือไม่โดยตรวจสอบว่าฟิลด์ข้อความที่ถูกแก้ไขในปัจจุบันใช้พื้นที่ว่างเหมือนกับคีย์บอร์ด: stackoverflow.com/a/28813720/6749410
HirdayGupta

คำตอบ:


710

นี่คือทางออกโดยไม่ต้องจัดการสวิตช์จากฟิลด์ข้อความหนึ่งไปยังอีก:

 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)            
    }   

func keyboardWillShow(notification: NSNotification) {            
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue() {
        self.view.frame.origin.y -= keyboardSize.height
    }            
}

func keyboardWillHide(notification: NSNotification) {
    self.view.frame.origin.y = 0
}

ในการแก้ปัญหานี้ให้แทนที่ทั้งสองฟังก์ชันkeyboardWillShow/Hideด้วยสิ่งเหล่านี้:

func keyboardWillShow(notification: NSNotification) {        
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue() {
        if view.frame.origin.y == 0 {
            self.view.frame.origin.y -= keyboardSize.height
        }
    }        
}

func keyboardWillHide(notification: NSNotification) {
    if view.frame.origin.y != 0 {
        self.view.frame.origin.y = 0
    }
}

แก้ไขสำหรับ SWIFT 3.0:

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

@objc func keyboardWillShow(notification: NSNotification) {        
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        if self.view.frame.origin.y == 0 {
            self.view.frame.origin.y -= keyboardSize.height
        }
    }        
}

@objc func keyboardWillHide(notification: NSNotification) {
    if self.view.frame.origin.y != 0 {
        self.view.frame.origin.y = 0
    }
}

แก้ไขสำหรับ SWIFT 4.0:

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

@objc func keyboardWillShow(notification: NSNotification) {        
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        if self.view.frame.origin.y == 0 {
            self.view.frame.origin.y -= keyboardSize.height
        }
    }        
}

@objc func keyboardWillHide(notification: NSNotification) {
    if self.view.frame.origin.y != 0 {
        self.view.frame.origin.y = 0
    }
}

แก้ไขสำหรับ SWIFT 4.2:

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

@objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        if self.view.frame.origin.y == 0 {
            self.view.frame.origin.y -= keyboardSize.height
        }
    }
}

@objc func keyboardWillHide(notification: NSNotification) {
    if self.view.frame.origin.y != 0 {
        self.view.frame.origin.y = 0
    }
}

56
หากผู้ใช้แตะที่ช่องข้อความอื่นในขณะที่แป้นพิมพ์ปรากฏอยู่มุมมองจะถูกผลักขึ้นซึ่งทำให้เกิดพื้นที่สีดำ (ขนาดของแป้นพิมพ์) - เราจำเป็นต้องแก้ไขด้วยการมีตัวแปรที่ติดตามว่าแป้นพิมพ์นั้นปรากฏอยู่หรือไม่ . เช่นถ้า keyboardPresent == จริงแล้วอย่าย้ายมุมมองแหล่งกำเนิด ฯลฯ ฯลฯ
jonprasetyo

3
@ Matthew Lin ใช้บูลีนเพื่อให้ฟังก์ชั่น keyboardWillShow และซ่อนทำงานได้ครั้งเดียวเท่านั้น
iluvatar_GR

11
ข้อเสนอแนะเพียงข้อเดียวเพื่อที่คุณจะได้ไม่ต้องแก้ไขข้อบกพร่องอย่างที่ฉันเคยทำ หากคุณมี uitextfield หลายอันบนหน้าจอเดียวกันขนาดของแป้นพิมพ์อาจแตกต่างกันไป (มันไม่แสดงคำแนะนำสำหรับอินพุตบางตัวตามการตั้งค่าของคุณ) ดังนั้นขอแนะนำให้ตั้งค่า self.view.frame.origin.y = 0 ทุกครั้ง คุณยกเลิกแป้นพิมพ์ ตัวอย่างเช่นมันจะแสดง sugeestions สำหรับฟิลด์ข้อความอีเมลของคุณดังนั้นขนาดแป้นพิมพ์จะเพิ่มขึ้นและจะไม่แสดงคำแนะนำสำหรับฟิลด์รหัสผ่านดังนั้นขนาดแป้นพิมพ์จะลดลง
Vandan Patel

36
คุณต้องใช้UIKeyboardFrameEndUserInfoKeyมากกว่าUIKeyboardFrameBeginUserInfoKeyเมื่อรับขนาดแป้นพิมพ์ ฉันไม่แน่ใจว่าทำไมในขณะนี้ แต่อดีตจะให้ผลลัพธ์ที่สอดคล้องกันมากขึ้น
jshapy8

3
โปรดแทนที่ด้วยUIKeyboardFrameBeginUserInfoKey UIKeyboardFrameEndUserInfoKeyคนแรกให้เริ่มต้นเฟรมของแป้นพิมพ์ซึ่งบางครั้งก็เป็นศูนย์ในขณะที่คนที่สองให้เฟรมท้ายของคีย์บอร์ด
Arnab

90

วิธีที่ง่ายที่สุดที่ไม่ต้องใช้รหัสใด ๆ :

  1. ดาวน์โหลดKeyboardLayoutConstraint.swiftและเพิ่ม (ลากและวาง) ไฟล์ลงในโครงการของคุณหากคุณไม่ได้ใช้เฟรมเวิร์กแอนิเมชันของ Spring อยู่แล้ว
  2. ในกระดานเรื่องราวของคุณสร้างข้อ จำกัด ด้านล่างสำหรับมุมมองหรือฟิลด์ข้อความเลือกข้อ จำกัด (ดับเบิลคลิกที่มัน) และในตัวตรวจสอบตัวตนให้เปลี่ยนคลาสจาก NSLayoutConstraint เป็น KeyboardLayoutConstraint
  3. ทำ!

วัตถุจะเลื่อนขึ้นโดยอัตโนมัติโดยใช้แป้นพิมพ์พร้อมกัน


4
ในการเลือกข้อ จำกัด ด้านล่างคุณสามารถไปที่ตัวตรวจสอบขนาดจากนั้นดับเบิลคลิกที่ข้อ จำกัด ในรายการ - raywenderlich.com/wp-content/uploads/2015/09/ …
gammachill

3
สิ่งนี้ทำงานได้สมบูรณ์แบบสำหรับฉัน มันเป็นกระบวนการที่แท้จริง 2 ขั้นตอน 1. เพิ่ม KeyboardLayoutConstraint.swift, 2. ในกระดานเรื่องราวสร้างข้อ จำกัด ด้านล่างสำหรับมุมมองหรือฟิลด์ข้อความ หมายเหตุ: ฉันลบข้อ จำกัด ของฉันและเพิ่มข้อ จำกัด เพียง 1 ข้อที่ด้านล่างของมุมมองหรือฟิลด์ข้อความและเปลี่ยนคลาสจาก NSLayoutConstraint เป็น KeyboardLayoutConstraint แล้วมุมมองใด ๆ / กรอบข้อความข้างต้นผม ฯลฯ จำกัด เพียงเชื่อมต่อจากรายการที่ไปยังรายการที่มี KeyboardLayoutConstraint เดียวและผลที่ได้คือรายการทั้งหมดในมุมมองของย้ายขึ้น / ลงเมื่อคณะกรรมการที่สำคัญปรากฏ / หายไป
ไบรอัน

4
นี่เป็นทางออกที่ดีที่สุดรหัสที่ให้ไม่ได้เป็นการยากที่จะระบุค่าใด ๆ เช่นความยาวหรือเส้นโค้งของภาพเคลื่อนไหวหรือขนาดของแป้นพิมพ์ นอกจากนี้ยังเข้าใจง่าย
miguelSantirso

3
สิ่งนี้ใช้ได้สำหรับฉัน แต่ฉันได้รับพื้นที่เพิ่มอีก 50px ระหว่างส่วนบนของแป้นพิมพ์และด้านล่างของ scrollView ของฉัน ฉันสงสัยว่าเป็นเพราะข้อ จำกัด ด้านล่างของพื้นที่ปลอดภัยที่ฉันใช้หรือไม่ ใครวิ่งเข้ามานี้
Clifton Labrum

1
นี่เป็นคำตอบที่ยอดเยี่ยม การออกแบบที่ยอดเยี่ยมเช่นกัน หนึ่งข้อเสนอแนะ: หาก textviews / textfields ของคุณอยู่ในเซลล์มุมมองตารางคุณอาจสังเกตเห็นมุมมองที่มีข้อ จำกัด นี้จะกระโดดขึ้นอย่างเชื่องช้าทุกครั้งที่ผู้ใช้คลิกป้อนและไปที่ช่องข้อความถัดไป คุณสามารถรวมภาพเคลื่อนไหวDispatchQueue.main.async {}เพื่อแก้ไข การทำงานที่ดี! ยกนิ้ว!
ScottyBlades

68

หนึ่งในคำตอบที่ได้รับความนิยมในหัวข้อนี้ใช้รหัสต่อไปนี้:

func keyboardWillShow(sender: NSNotification) {
    self.view.frame.origin.y -= 150
}
func keyboardWillHide(sender: NSNotification) {
    self.view.frame.origin.y += 150
}

มีปัญหาที่ชัดเจนเกี่ยวกับการชดเชยมุมมองของคุณด้วยจำนวนคงที่ มันจะดูดีในอุปกรณ์หนึ่ง แต่จะดูไม่ดีกับการกำหนดค่าขนาดอื่น คุณจะต้องได้รับความสูงของแป้นพิมพ์และใช้เป็นค่าชดเชยของคุณ

นี่คือวิธีการแก้ปัญหาที่ทำงานบนอุปกรณ์ทั้งหมดและจัดการกับตัวพิมพ์เล็ก - ใหญ่ที่ผู้ใช้ซ่อนฟิลด์ข้อความคาดเดาขณะพิมพ์

สารละลาย

สิ่งสำคัญที่ควรทราบด้านล่างนี้คือสิ่งที่เรากำลังส่งผ่าน self.view.window เป็นพารามิเตอร์วัตถุของเรา สิ่งนี้จะให้ข้อมูลจากคีย์บอร์ดของเราเช่นความสูงของมัน!

@IBOutlet weak var messageField: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: self.view.window)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: self.view.window)
}

func keyboardWillHide(sender: NSNotification) {
    let userInfo: [NSObject : AnyObject] = sender.userInfo!
    let keyboardSize: CGSize = userInfo[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue.size
    self.view.frame.origin.y += keyboardSize.height
}

เราจะทำให้มันดูดีในทุกอุปกรณ์และจัดการกับกรณีที่ผู้ใช้เพิ่มหรือลบฟิลด์ข้อความคาดการณ์

func keyboardWillShow(sender: NSNotification) {
    let userInfo: [NSObject : AnyObject] = sender.userInfo!
    let keyboardSize: CGSize = userInfo[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue.size
    let offset: CGSize = userInfo[UIKeyboardFrameEndUserInfoKey]!.CGRectValue.size

    if keyboardSize.height == offset.height {
        UIView.animateWithDuration(0.1, animations: { () -> Void in
            self.view.frame.origin.y -= keyboardSize.height
        })
    } else {
        UIView.animateWithDuration(0.1, animations: { () -> Void in
            self.view.frame.origin.y += keyboardSize.height - offset.height
        })
    }
}

ลบผู้สังเกตการณ์

อย่าลืมลบผู้สังเกตการณ์ก่อนที่จะออกจากมุมมองเพื่อป้องกันไม่ให้มีการส่งข้อความที่ไม่จำเป็น

override func viewWillDisappear(animated: Bool) {
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: self.view.window)
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: self.view.window)
}

อัปเดตตามคำถามจากความคิดเห็น:

หากคุณมีฟิลด์ข้อความอย่างน้อยสองฟิลด์คุณสามารถตรวจสอบเพื่อดูว่า view.frame.origin.y ของคุณอยู่ที่ศูนย์หรือไม่

func keyboardWillShow(sender: NSNotification) {
    let userInfo: [NSObject : AnyObject] = sender.userInfo!

    let keyboardSize: CGSize = userInfo[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue.size
    let offset: CGSize = userInfo[UIKeyboardFrameEndUserInfoKey]!.CGRectValue.size

    if keyboardSize.height == offset.height {
        if self.view.frame.origin.y == 0 {
            UIView.animateWithDuration(0.1, animations: { () -> Void in
                self.view.frame.origin.y -= keyboardSize.height
            })
        }
    } else {
        UIView.animateWithDuration(0.1, animations: { () -> Void in
            self.view.frame.origin.y += keyboardSize.height - offset.height
        })
    }
     print(self.view.frame.origin.y)
}

1
เมื่อต้องรับมือกับฟิลด์ข้อความจำนวนมากมุมมองจะขยับขึ้นเรื่อย ๆ และไม่กลับมาลงอีก
Mugunthan Balakrishnan

คุณจะต้องเปลี่ยนเงื่อนไขของคุณเพื่อบัญชีสำหรับช่องข้อความ
Dan Beaulieu

ขอบคุณสำหรับการตอบสนองฉันพบคำตอบที่ฉันกำลังมองหาที่หัวข้อนี้ใน stack overflow stackoverflow.com/questions/1126726/ …
Mugunthan Balakrishnan

@MugunthanBalakrishnan ขอบคุณที่นำสิ่งนี้มาฉันได้เพิ่มวิธีแก้ปัญหา
Dan Beaulieu

สวัสดีพวกมีข้อผิดพลาด ผู้สังเกตการณ์จะไม่ถูกลบออกจากมุมมองหลังจากถูกเรียกใน viewWillDisappear แทนที่บรรทัดนี้ "NSNotificationCenter.defaultCenter (). RemoveObserver (ตัวเองชื่อ: UIKeyboardWillHideNotification) วัตถุ: self.view.window)" ด้วย "NSNotificationCenter.defaultCenter () ลบตัวบันทึกการทำงาน (ตัวเองชื่อ) ถูกลบ
rudald

29

เพิ่มสิ่งนี้ลงใน viewcontroller ของคุณ ทำงานเหมือนจับใจ เพียงปรับค่าต่างๆ

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

@objc func keyboardWillShow(sender: NSNotification) {
    self.view.frame.origin.y -= 150
}
@objc func keyboardWillHide(sender: NSNotification) {
    self.view.frame.origin.y += 150
}

มันใช้งานได้สำหรับฉัน อย่างไรก็ตามมันค่อนข้างกระตุก ฉันจะทำให้มันเลื่อนขึ้นสมูทเลย์ได้อย่างไร ยังมีวิธีที่จะนำไปใช้กับหนึ่งใน textfields เช่นนี้มันทำเพื่อทุกคน :(
DannieCoderBoi

2
อาจไม่ทำงานกับ "เลย์เอาต์อัตโนมัติ" ดังนั้นให้ลองปิดใช้งานถ้าเป็นเช่นนั้น
Teodor Ciuraru

1
มันทำให้เกิดพฤติกรรมขี้ขลาดกับ autolayout @Josh คุณเข้าใจผิด
Mike

5
อย่าทำอย่างนี้! คุณไม่สามารถคิดว่าคีย์บอร์ดมีขนาดที่แน่นอน
nielsbot

2
ควรใช้ keyboardSize จะเกิดอะไรขึ้นเมื่อคุณมีมุมมองอุปกรณ์เสริมและความสูงของคีย์บอร์ดบนอุปกรณ์ต่าง ๆ แป้นพิมพ์เดี่ยว?
xtrinch

25

ฉันปรับปรุงหนึ่งในคำตอบเล็กน้อยเพื่อให้ใช้งานกับแป้นพิมพ์ที่แตกต่างกันและ textviews / ฟิลด์ที่แตกต่างกันในหน้าเดียว:

เพิ่มผู้สังเกตการณ์:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange(notification:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)

    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}

func keyboardWillHide() {
    self.view.frame.origin.y = 0
}

func keyboardWillChange(notification: NSNotification) {

    if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        if YOURTEXTVIEW.isFirstResponder {
            self.view.frame.origin.y = -keyboardSize.height
        }
    }
}

ลบผู้สังเกตการณ์:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
    NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
}

3
วิธีนี้ใช้ได้ดีกว่าคำตอบที่ยอมรับ ได้รับการยืนยันคำตอบที่แสดงให้เห็นแป้นพิมพ์เพียงครั้งเดียวที่ฉันเป็นปัญหา :)
Masih

ใช้งานได้กับ Xcode 10.1 และ iOS 12 คำตอบที่ยอมรับไม่ถูกต้องอีกต่อไป
Zeeshan

นี่เป็นคำตอบที่ยอดเยี่ยมสิ่งเดียวที่ฉันจะเพิ่มคือการติดตามบริเวณที่ปลอดภัยด้านล่างในอุปกรณ์รุ่นใหม่ (X, XS และอื่น ๆ ) เพื่อให้บัญชีนั้น
Munib

@Munib ดูstackoverflow.com/a/54993623/1485230ปัญหาอื่น ๆ รวมถึงมุมมองที่ไม่ได้เคลื่อนไหวและความสูงของแป้นพิมพ์ไม่ได้ถูกติดตาม
Antzi

เกิดอะไรขึ้นถ้าฟิลด์ข้อความของฉันอยู่ด้านบนของมุมมอง .. ? ฉันหมายถึงถ้ามีฟิลด์ข้อความที่มีจุดกำเนิด Y = 0 .. ?? จากนั้นฟิลด์ข้อความกำลังจะขึ้นและฉันไม่เห็นมันเลย
Saifan Nadaf

18

ไม่ใช่โฆษณาหรือการส่งเสริมการขายหรือสแปมเป็นเพียงทางออกที่ดี ฉันรู้ว่าคำถามนี้มีเกือบ 30 คำตอบและฉันก็ตกใจที่ไม่มีใครพูดถึงครั้งหนึ่งเกี่ยวกับโครงการ GitHub ที่สวยงามนี้ที่ทำเพื่อคุณและดียิ่งขึ้น คำตอบทั้งหมดเพียงเลื่อนมุมมองขึ้นด้านบน ฉันเพิ่งแก้ไขปัญหาทั้งหมดด้วย IQKeyboardManager นี้ มันมีดาวมากกว่า 13,000 ดวง
เพียงเพิ่มไฟล์นี้ใน podfile ของคุณหากคุณใช้งาน swift

pod 'IQKeyboardManagerSwift'

แล้วใน AppDelegate.swift ของคุณก็ทำได้ import IQKeyboardManagerSwift

import IQKeyboardManagerSwift

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

      IQKeyboardManager.shared.enable = true // just add this line

      return true
    }
}

เพิ่มบรรทัดIQKeyboardManager.shared.enable = trueเพื่อเปิดใช้งาน
โซลูชันนี้เป็นสิ่งจำเป็นถ้าคุณกำลังจะผลิต


นี่เป็นสิ่งที่ดีจริงๆ แต่เวอร์ชันล่าสุดใช้งานไม่ได้สำหรับฉันฉันใช้ 6.2.1 และนำเข้าimport IQKeyboardManagerและใช้IQKeyboardManager.shared().isEnabled = trueใน AppDelegate
Dhanu K

2
และมันใช้งานได้ดีมากเมื่อใช้การแก้ไขหลายข้อความซึ่งจะช่วยประหยัดเวลาของฉัน
Dhanu K

1
ไม่สามารถขอบคุณมากพอสำหรับการชี้ไปที่ห้องสมุดที่ยอดเยี่ยมนี้ ในที่สุดห้องสมุดนี้ก็เป็นคำตอบสุดท้ายสำหรับเรื่องไร้สาระที่เกี่ยวข้องกับแป้นพิมพ์ทั้งหมดซึ่ง Apple ไม่เคยให้บริการ ตอนนี้ฉันจะใช้มันกับทุกโปรเจคของฉันทั้งเก่าและใหม่และประหยัดเวลาและปวดหัวซึ่งคีย์บอร์ดนี้ปรากฏขึ้นหายไปหรือไม่หายไปหรือจะซ่อนมันได้อย่างไรและทำไมมันซ้อนทับกัน วันที่ฉันเขียนโปรแกรมสำหรับ iPhone
zeeshan

1
ฉันเขียนโค้ดของตัวเองเพื่อย้ายฟิลด์ข้อความเหมือนกับโซลูชันอื่น ๆ ที่นี่ ฉันพบว่า IQKeyboardManager นั้นดีมากและฉันจะรวมมันต่อจากนี้ไป จะทำให้รหัสของฉันมีประโยชน์ในกรณีที่กรอบไม่ได้รับการปรับปรุง
TM Lynch

@DhanuK เพิ่งพบห้องสมุดนี้และทำงานได้อย่างสมบูรณ์แบบและไม่ต้องพยายาม รหัสผู้แทนแอปได้รับการอัพเดตเป็น IQKeyboardManager.shared.enable = true
adougies

15

สำหรับข้อผิดพลาดหน้าจอสีดำ (สวิฟท์ที่ 4 และ 4.2)

ฉันแก้ไขปัญหาหน้าจอสีดำ ในโซลูชันที่ตรวจสอบแล้วความสูงของแป้นพิมพ์จะเปลี่ยนไปหลังจากการแตะ

ต้องใช้UIKeyboardFrameEndUserInfoKeyแทน UIKeyboardFrameBeginUserInfoKey

var isKeyboardAppear = false

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

@objc func keyboardWillShow(notification: NSNotification) {
    if !isKeyboardAppear {
        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
            if self.view.frame.origin.y == 0{
                self.view.frame.origin.y -= keyboardSize.height
            }
        }
        isKeyboardAppear = true
    }
}

@objc func keyboardWillHide(notification: NSNotification) {
    if isKeyboardAppear {
        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
            if self.view.frame.origin.y != 0{
                self.view.frame.origin.y += keyboardSize.height
            }
        }
         isKeyboardAppear = false
    }
}

จะไม่ทำงานหากมี tabbar คุณต้องคำนวณความสูงของ Tabbar มิฉะนั้นจะมีช่องว่างระหว่างหน้าจอสีดำระหว่างคีย์บอร์ดกับมุมมอง
Ankur Lahiry

นี่ไม่ได้แก้ไขพื้นที่สีดำที่แป้นพิมพ์อยู่ใน iPhone X และใหม่กว่า และทุกครั้งที่คีย์บอร์ดปรากฏขึ้นและหายไปมุมมองหลักจะเลื่อนลง
Edison

14

ฉันเห็นคำตอบทั้งหมดย้ายมุมมองตัวเองตามค่าของความสูงของแป้นพิมพ์ ดีฉันมีคำตอบที่ซับซ้อนซึ่งอาจเป็นประโยชน์หากคุณใช้ข้อ จำกัด เช่นautolayoutที่ย้ายมุมมองโดยการเปลี่ยนค่าข้อ จำกัด (ตัวอย่างเช่นข้อ จำกัด ด้านล่างหรือด้านบน) โดยค่าที่กำหนดไว้ล่วงหน้าหรือคุณสามารถใช้ค่าขนาดแป้นพิมพ์

ในตัวอย่างนี้ฉันใช้ข้อ จำกัด ด้านล่างจากฟิลด์ข้อความถึงมุมมองเค้าโครงด้านล่างด้วยค่าเริ่มต้นที่ 175

@IBOutlet weak var bottomConstraint: NSLayoutConstraint!

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);
}

func keyboardWillShow(notification: NSNotification) {
    //To retrieve keyboard size, uncomment following line
    //let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue()
    bottomConstraint.constant = 260
    UIView.animateWithDuration(0.3) {
        self.view.layoutIfNeeded()
    }
}

func keyboardWillHide(notification: NSNotification) {
    //To retrieve keyboard size, uncomment following line
    //let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue()
    bottomConstraint.constant = 175
    UIView.animateWithDuration(0.3) {
        self.view.layoutIfNeeded()
    }
}

สวัสดีคุณช่วยบอกฉันหน่อยได้ไหมว่าทำไมมันถึงใช้งานไม่ได้เมื่ออยู่ในมุมมองที่มี TableView ด้วย มันทำงานได้ดีในสถานการณ์เดียวกันเมื่อมี CollectionView
elarcoiris

9

มีการเปลี่ยนแปลงเล็กน้อยกับวิธีที่เรากำหนด KeyboardWillHideNotification

วิธีนี้ใช้ได้กับSwift 4.2 :

NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)


@objc func keyboardWillShow(_ notification:Notification) {
    if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        self.view.frame.origin.y -= keyboardSize.height
    }
}

@objc func keyboardWillHide(_ notification:Notification) {
    if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        self.view.frame.origin.y += keyboardSize.height
    }
}

2
เกิดอะไรขึ้นถ้าฟิลด์ข้อความของฉันอยู่ด้านบนของมุมมอง .. ? ฉันหมายถึงถ้ามีฟิลด์ข้อความที่มีจุดกำเนิด Y = 0 .. ?? จากนั้นฟิลด์ข้อความกำลังจะขึ้นและฉันไม่เห็นมัน
Saifan Nadaf

7

สวิฟท์ 5.0:

หลังจากการต่อสู้ 4-5 ชั่วโมงฉันก็มาพร้อมกับนามสกุลของ UIViewController ที่เรียบง่ายพร้อมโค้ดง่าย ๆ ที่ใช้งานได้อย่างมีเสน่ห์

* มุมมองไม่ควรเคลื่อนไหวเมื่อ TextField อยู่เหนือแป้นพิมพ์

* ไม่จำเป็นต้องตั้งค่าคงที่เป็น NSLayoutConstraint

* ไม่ต้องใช้ห้องสมุดบุคคลที่สาม

* ไม่จำเป็นต้องใช้รหัสภาพเคลื่อนไหว

* ทำงานบน tableview เช่นกัน

* ใช้งานได้กับเลย์เอาต์อัตโนมัติ / ปรับขนาดอัตโนมัติ

extension UIViewController {
    func addKeyboardObserver() {
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardNotifications(notification:)),
                                               name: UIResponder.keyboardWillChangeFrameNotification,
                                               object: nil)
    }

    func removeKeyboardObserver(){
        NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
    }

    // This method will notify when keyboard appears/ dissapears
    @objc func keyboardNotifications(notification: NSNotification) {

        var txtFieldY : CGFloat = 0.0  //Using this we will calculate the selected textFields Y Position
        let spaceBetweenTxtFieldAndKeyboard : CGFloat = 5.0 //Specify the space between textfield and keyboard


        var frame = CGRect(x: 0, y: 0, width: 0, height: 0)
        if let activeTextField = UIResponder.currentFirst() as? UITextField ?? UIResponder.currentFirst() as? UITextView {
            // Here we will get accurate frame of textField which is selected if there are multiple textfields
            frame = self.view.convert(activeTextField.frame, from:activeTextField.superview)
            txtFieldY = frame.origin.y + frame.size.height
        }

        if let userInfo = notification.userInfo {
            // here we will get frame of keyBoard (i.e. x, y, width, height)
            let keyBoardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
            let keyBoardFrameY = keyBoardFrame!.origin.y
            let keyBoardFrameHeight = keyBoardFrame!.size.height

            var viewOriginY: CGFloat = 0.0
            //Check keyboards Y position and according to that move view up and down
            if keyBoardFrameY >= UIScreen.main.bounds.size.height {
                viewOriginY = 0.0
            } else {
                // if textfields y is greater than keyboards y then only move View to up
                if txtFieldY >= keyBoardFrameY {

                    viewOriginY = (txtFieldY - keyBoardFrameY) + spaceBetweenTxtFieldAndKeyboard

                    //This condition is just to check viewOriginY should not be greator than keyboard height
                    // if its more than keyboard height then there will be black space on the top of keyboard.
                    if viewOriginY > keyBoardFrameHeight { viewOriginY = keyBoardFrameHeight }
                }
            }

            //set the Y position of view
            self.view.frame.origin.y = -viewOriginY
        }
    }
}

เพิ่มส่วนขยายของ UIResponder นี้เพื่อรับ TextField ที่เลือก

extension UIResponder {

    static weak var responder: UIResponder?

    static func currentFirst() -> UIResponder? {
        responder = nil
        UIApplication.shared.sendAction(#selector(trap), to: nil, from: nil, for: nil)
        return responder
    }

    @objc private func trap() {
        UIResponder.responder = self
    }
}

จากนั้นใช้สิ่งนี้ใน ViewController ใด ๆ ของคุณ

   override func viewWillAppear(_ animated: Bool) {
        self.addKeyboardObserver()
    }

    override func viewWillDisappear(_ animated: Bool) {
        self.removeKeyboardObserver()
    }


นี่ดูเหมือนเป็นทางออกที่ดีที่สุด แต่มีข้อบกพร่องอยู่สองสามข้อ 1, textfield ขยับขึ้น แต่เมื่อฉันเริ่มพิมพ์มันกระโดดขึ้นเล็กน้อย 2, ในแนวนอนเมื่อพิมพ์ข้อความฟิลด์บางครั้งกระโดดไปทางซ้าย
Darren

@Darren ฉันกำลังพยายามหาจุดบกพร่องเหล่านี้ แต่ฉันไม่พบคุณช่วยกรุณาบอกที่คุณมีข้อบกพร่องเหล่านี้ฉันหมายถึงที่รุ่น / อุปกรณ์ ... ??
Saifan Nadaf

6

สำหรับ Swift 3 ฉันสร้างคลาสย่อย UIViewController เนื่องจากฉันต้องการพฤติกรรมคงที่ใน View Controller ทั้งหมด

class SomeClassVC: UIViewController {

  //MARK: - Lifecycle
  override func viewDidLoad() {
    super.viewDidLoad()

    addKeyboardObservers()
  }

  override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    removeKeyboardObservers()
  }

  //MARK: - Overrides
  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    view.endEditing(true)
  }

  //MARK: - Help
  func addKeyboardObservers() {
    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
  }

  func removeKeyboardObservers() {
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: self.view.window)
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: self.view.window)
  }

  func keyboardWillShow(notification: NSNotification) {
    let keyboardHeight = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.height
    UIView.animate(withDuration: 0.1, animations: { () -> Void in
      self.view.window?.frame.origin.y = -1 * keyboardHeight!
      self.view.layoutIfNeeded()
    })
  }

  func keyboardWillHide(notification: NSNotification) {
    UIView.animate(withDuration: 0.1, animations: { () -> Void in
      self.view.window?.frame.origin.y = 0
      self.view.layoutIfNeeded()
    })
  }

  func resignTextFieldFirstResponders() {
    for textField in self.view.subviews where textField is UITextField {
      textField.resignFirstResponder()
    }
  }

  func resignAllFirstResponders() {
      view.endEditing(true)
  }
}

โดยได้รับแรงบันดาลใจจากวิธีแก้ปัญหาของ Pavle ฉันได้อัพเกรดมันเพื่อยกระดับแป้นพิมพ์โดยอัตโนมัติด้วยเปอร์เซ็นต์ที่เหลือของพื้นที่ว่างที่เหลืออยู่และค้นหาฟิลด์โฟกัสที่วนซ้ำเพื่อการจัดวางที่เหมาะสม หยิบมาที่นี่: gist.github.com/noordawod/24d32b2ce8363627ea73d7e5991009a0
Noor Dawod

แถบแท็บของฉันขยับขึ้นมาพร้อมหน้าต่าง! :(
Alfi

6

คำตอบที่ตรวจสอบแล้วไม่ได้คำนึงถึงตำแหน่งของ textfieldและมีข้อผิดพลาดบางอย่าง (การกระจัดสองครั้งไม่เคยกลับมาที่ตำแหน่งหลักการกระจัดแม้ว่า texfield อยู่ด้านบนของมุมมอง ... )

ความคิดคือ:

  • เพื่อรับโฟกัส TextField ตำแหน่ง Y แบบสัมบูรณ์
  • เพื่อรับความสูงของแป้นพิมพ์
  • เพื่อรับ ScreenHeight
  • จากนั้นคำนวณระยะห่างระหว่างตำแหน่งแป้นพิมพ์และฟิลด์ข้อความ (หาก <0 -> เลื่อนมุมมองขึ้น
  • การใช้ UIView.transform แทน UIView.frame.origin.y - = .. ทำให้กลับมาอยู่ในตำแหน่งเดิมได้ง่ายขึ้นด้วย UIView.transform = .identity

จากนั้นเราจะสามารถย้ายมุมมองเฉพาะในกรณีที่จำเป็นและของการกระจัดที่เฉพาะเจาะจงในคนอื่น ๆ ที่จะมี texField ที่มุ่งเน้นเพียงแค่บนแป้นพิมพ์

นี่คือรหัส:

สวิฟต์ 4

class ViewController: UIViewController, UITextFieldDelegate {

var textFieldRealYPosition: CGFloat = 0.0

override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector: #selector(VehiculeViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(VehiculeViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

  // Delegate all textfields

}


@objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        let distanceBetweenTextfielAndKeyboard = self.view.frame.height - textFieldRealYPosition - keyboardSize.height
        if distanceBetweenTextfielAndKeyboard < 0 {
            UIView.animate(withDuration: 0.4) {
                self.view.transform = CGAffineTransform(translationX: 0.0, y: distanceBetweenTextfielAndKeyboard)
            }
        }
    }
}


@objc func keyboardWillHide(notification: NSNotification) {
    UIView.animate(withDuration: 0.4) {
        self.view.transform = .identity
    }
}


func textFieldDidBeginEditing(_ textField: UITextField) {
  textFieldRealYPosition = textField.frame.origin.y + textField.frame.height
  //take in account all superviews from textfield and potential contentOffset if you are using tableview to calculate the real position
}

}


ดีมาก! (ใน viewDidLoad คุณมี "VehiculeViewController" แทนที่จะเป็น "ViewController")
rene

คำตอบที่สมบูรณ์และมีประโยชน์มากขึ้น ขอบคุณ! ฉันขอแนะนำว่าการตรวจสอบแป้นพิมพ์ถูกเรียกดังต่อไปนี้เพราะมันจะให้ขนาดที่สอดคล้องกันของคีย์บอร์ด ......... ถ้าให้ keyboardSize = (notification.userInfo? [UIResponder.keyboardFrameEndUserInfoKey] เป็น? NSValue)? cgRectValue .size
เบน

4

ฉันสังเกตเห็นว่าคำตอบอื่น ๆ เกี่ยวข้องกับการตัดบางส่วนจากมุมมอง หากคุณต้องการปรับขนาดมุมมองโดยไม่ต้องตัดเนื้อหาใด ๆ เพียงลองวิธีนี้ :)

func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
        self.view.setTranslatesAutoresizingMaskIntoConstraints(true)
        self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.height - keyboardSize.height)
    }
}

func keyboardWillHide(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
        self.collectionView.setTranslatesAutoresizingMaskIntoConstraints(false)
        self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.height + keyboardSize.height)
    }
}

4

สองเซ็นต์ของฉันสำหรับผู้เริ่มต้น: จากตัวอย่างด้านบนบางคนเปลี่ยนพิกัด, การใช้งานอื่น ๆ "หน้ากากปรับขนาดอัตโนมัติ" และข้อ จำกัด อื่น ๆ :

อย่างที่ Apple บอกห้ามผสมตรรกะทั้งสามประเภทนี้ หากคุณมีข้อ จำกัด ในกระดานเรื่องราวอย่าพยายามเปลี่ยน x / y มันไม่ทำงานแน่นอน


4

ดังนั้นไม่มีคำตอบอื่นใดที่ดูเหมือนจะทำให้ถูกต้อง

แป้นพิมพ์พฤติกรรมที่ดีบน iOS ควร:

  • ปรับขนาดโดยอัตโนมัติเมื่อคีย์บอร์ดเปลี่ยนขนาด (ใช่ใช่)
  • เคลื่อนไหวด้วยความเร็วเดียวกับแป้นพิมพ์
  • เคลื่อนไหวโดยใช้เส้นโค้งเดียวกับแป้นพิมพ์
  • เคารพในพื้นที่ปลอดภัยหากเกี่ยวข้อง
  • ใช้งานได้ในโหมด iPad / Undocked ด้วย

รหัสของฉันใช้NSLayoutConstraintประกาศเป็น@IBOutlet

@IBOutlet private var bottomLayoutConstraint: NSLayoutConstraint!

คุณยังสามารถใช้การแปลงดูการชดเชย ... ฉันคิดว่ามันง่ายกว่าด้วยข้อ จำกัด มันทำงานได้โดยการตั้งค่าข้อ จำกัด ที่ด้านล่างคุณอาจต้องเปลี่ยนรหัสถ้าค่าคงที่ของคุณไม่ใช่ 0 / ไม่ใช่ที่ด้านล่าง

นี่คือรหัส:

// In ViewDidLoad
    NotificationCenter.default.addObserver(self, selector: #selector(?MyViewController.keyboardDidChange), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)


@objc func keyboardDidChange(notification: Notification) {
    let userInfo = notification.userInfo! as [AnyHashable: Any]
    let endFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
    let animationDuration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as! NSNumber
    let animationCurve = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as! NSNumber
    bottomLayoutConstraint.constant = view.frame.height - endFrame.origin.y - view.safeAreaInsets.bottom // If your constraint is not defined as a safeArea constraint you might want to skip the last part.
    // Prevents iPad undocked keyboard.
    guard endFrame.height != 0, view.frame.height == endFrame.height + endFrame.origin.y else {
        bottomLayoutConstraint.constant = 0
        return
    }
    UIView.setAnimationCurve(UIView.AnimationCurve(rawValue: animationCurve.intValue)!)
    UIView.animate(withDuration: animationDuration.doubleValue) {
        self.view.layoutIfNeeded()
        // Do additional tasks such as scrolling in a UICollectionView
    }
}

3

100% คำตอบที่สมบูรณ์แบบสำหรับทุกความอัปเดตความสูงของ Tableview เมื่อเปิดคีย์บอร์ด

สำหรับ Swift4.2

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

      NotificationCenter.default.addObserver(self, selector: #selector(RecipeVC.keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
   }

   @objc func keyboardWillShow(notification: NSNotification) {
    if ((notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue) != nil {

        var userInfo = notification.userInfo!
        var keyboardFrame:CGRect = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
        keyboardFrame = self.view.convert(keyboardFrame, from: nil)

        var contentInset:UIEdgeInsets = self.tbl.contentInset
          contentInset.bottom = keyboardFrame.size.height
          self.tbl.contentInset = contentInset
    }
}

   @objc func keyboardWillHide(notification: NSNotification) {
    if ((notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue) != nil {
        let contentInset:UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        self.tbl.contentInset = contentInset
    }
}

Swift3.2

    override func viewDidLoad() {
          super.viewDidLoad()

           NotificationCenter.default.addObserver(self, selector: #selector(RecipeVC.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)

           NotificationCenter.default.addObserver(self, selector: #selector(RecipeVC.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    }
    func keyboardWillShow(notification: NSNotification) {
         if ((notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue) != nil {
         //self.view.frame.origin.y -= keyboardSize.height
         var userInfo = notification.userInfo!
         var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
          keyboardFrame = self.view.convert(keyboardFrame, from: nil)

          var contentInset:UIEdgeInsets = self.tbl.contentInset
          contentInset.bottom = keyboardFrame.size.height
          self.tbl.contentInset = contentInset

       }
    }

    func keyboardWillHide(notification: NSNotification) {
         if ((notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue) != nil {
         let contentInset:UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
         self.tbl.contentInset = contentInset
         }
    }

นี่คือคำตอบที่ดีที่สุด tbl ควรเป็น tableView และฉันได้เพิ่มส่วนเสริมบางส่วน: contentInset.bottom = keyboardFrame.size.height + 10
iphaaw

2

สำหรับSwift 3

func textFieldDidBeginEditing(_ textField: UITextField) { // became first responder

    //move textfields up
    let myScreenRect: CGRect = UIScreen.main.bounds
    let keyboardHeight : CGFloat = 216

    UIView.beginAnimations( "animateView", context: nil)
    var movementDuration:TimeInterval = 0.35
    var needToMove: CGFloat = 0

    var frame : CGRect = self.view.frame
    if (textField.frame.origin.y + textField.frame.size.height + UIApplication.shared.statusBarFrame.size.height > (myScreenRect.size.height - keyboardHeight - 30)) {
        needToMove = (textField.frame.origin.y + textField.frame.size.height + UIApplication.shared.statusBarFrame.size.height) - (myScreenRect.size.height - keyboardHeight - 30);
    }

    frame.origin.y = -needToMove
    self.view.frame = frame
    UIView.commitAnimations()
}

func textFieldDidEndEditing(_ textField: UITextField) {
    //move textfields back down
    UIView.beginAnimations( "animateView", context: nil)
    var movementDuration:TimeInterval = 0.35
    var frame : CGRect = self.view.frame
    frame.origin.y = 0
    self.view.frame = frame
    UIView.commitAnimations()
}

2

สวิฟท์ 4:

ฉันมีปัญหากับคำตอบที่ได้รับการยอมรับมากที่สุดซึ่งการซ่อนแป้นพิมพ์ไม่ได้ส่งมุมมองกลับไปที่ด้านล่างของหน้าเว็บ (เพียงบางส่วนเท่านั้น) สิ่งนี้ใช้ได้สำหรับฉัน (+ อัปเดตสำหรับ Swift 4)

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

@objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        if self.view.frame.origin.y == 0{
            self.view.frame.origin.y -= keyboardSize.height
        }
    }
}

@objc func keyboardWillHide(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        if self.view.frame.origin.y != 0{
            self.view.frame.origin.y = 0
        }
    }
}

เกิดอะไรขึ้นถ้าฟิลด์ข้อความของฉันอยู่ด้านบนของมุมมอง .. ? ฉันหมายถึงถ้ามีฟิลด์ข้อความที่มีจุดกำเนิด Y = 0 .. ?? จากนั้นฟิลด์ข้อความกำลังจะขึ้นและฉันไม่เห็นมัน
Saifan Nadaf

2

คล้ายกับ @Boris คำตอบ แต่ในSwift 5 :

override func viewDidLoad() {
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}

@IBAction func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        if self.view.frame.origin.y == 0 {
            self.view.frame.origin.y -= keyboardSize.height
        }
    }
}

@IBAction func keyboardWillHide(notification: NSNotification) {
    if self.view.frame.origin.y != 0 {
        self.view.frame.origin.y = 0
    }
}

1

นี่คือวิธีแก้ปัญหาของฉัน (อันที่จริงรหัสนี้ใช้สำหรับกรณีเมื่อคุณมี textfields ไม่กี่ตัวในมุมมองของคุณมันใช้งานได้กับกรณีที่คุณมี textfield เดียว)

class MyViewController: UIViewController, UITextFieldDelegate {

@IBOutlet weak var firstTextField: UITextField!
@IBOutlet weak var secondTextField: UITextField!

var activeTextField: UITextField!
var viewWasMoved: Bool = false


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

override func viewDidDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

func textFieldDidBeginEditing(textField: UITextField) {
    self.activeTextField = textField
}

func textFieldDidEndEditing(textField: UITextField) {
    self.activeTextField = nil
}

func textFieldShouldReturn(textField: UITextField) -> Bool {
    textField.resignFirstResponder()
    return true
}


func keyboardWillShow(notification: NSNotification) {

    let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue()

    var aRect: CGRect = self.view.frame
    aRect.size.height -= keyboardSize!.height

    let activeTextFieldRect: CGRect? = activeTextField?.frame
    let activeTextFieldOrigin: CGPoint? = activeTextFieldRect?.origin

    if (!CGRectContainsPoint(aRect, activeTextFieldOrigin!)) {
        self.viewWasMoved = true
        self.view.frame.origin.y -= keyboardSize!.height
    } else {
        self.viewWasMoved = false
    }
}

func keyboardWillHide(notification: NSNotification) {
    if (self.viewWasMoved) {
        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
            self.view.frame.origin.y += keyboardSize.height
        }
    }
}

อย่าลืมตั้งค่ามอบหมายให้เป็นฟิลด์ข้อความ
SwingerDinger

เปลี่ยนเงื่อนไขในคีย์บอร์ดจะแสดงเป็นถ้า (! CGRectContainsPoint (aRect, newOrgin!) &&! self.viewWasMoved)
KingofBliss

เพิ่ม self.viewWasMoved = false เมื่อคุณรีเซ็ตเฟรม
KingofBliss

1

อัปเดตสำหรับ Swift 3 ...

อย่างที่คนอื่น ๆ พูดคุณต้องเพิ่มผู้สังเกตการณ์การแจ้งเตือนในตัวควบคุม viewDidLoad () ของตัวควบคุมดังนี้:

NotificationCenter.default.addObserver(forName: .UIKeyboardWillShow, object: nil, queue: nil)
    { notification in
    self.keyboardWillShow(notification)
    }

NotificationCenter.default.addObserver(forName: .UIKeyboardWillHide, object: nil, queue: nil)
    { notification in
    self.keyboardWillHide(notification)
    }

NotificationCenter.default.addObserver(forName: .UIKeyboardDidShow, object: nil, queue: nil)
    { _ in
    self.enableUserInteraction()
    }

NotificationCenter.default.addObserver(forName: .UIKeyboardDidHide, object: nil, queue: nil)
    { _ in
    self.enableUserInteraction()
    }

อย่าลืมลบผู้สังเกตการณ์ของคุณตามความเหมาะสม (ฉันทำในเมธอด viewWillDisappear ())

NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardDidShow, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardDidHide, object: nil)

จากนั้นใช้วิธีการแสดงและซ่อนของคุณสังเกตเห็นบรรทัดที่บอกให้แอปพลิเคชันละเว้นเหตุการณ์การโต้ตอบ (startIgnoringInteractionEvents) นี่เป็นสิ่งสำคัญเนื่องจากไม่มีผู้ใช้สามารถแตะบนฟิลด์หรือแม้แต่เลื่อนดูและทำให้การเปลี่ยนแปลงเกิดขึ้นเป็นครั้งที่สองส่งผลให้เกิดข้อผิดพลาด UI ที่แย่มาก การไม่สนใจเหตุการณ์การโต้ตอบก่อนที่คีย์บอร์ดจะแสดงและซ่อนจะทำให้สิ่งนี้:

func keyboardWillShow(notification: Notification)
    {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue
        {
        UIApplication.shared.beginIgnoringInteractionEvents()
        self.view.frame.origin.y -= keyboardSize.height
        // add this line if you are shifting a scrollView, as in a chat application
        self.timelineCollectionView.contentInset.top += keyboardSize.height
        }
    }

func keyboardWillHide(notification: Notification)
    {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue
        {
        UIApplication.shared.beginIgnoringInteractionEvents()
        self.view.frame.origin.y += keyboardSize.height
        // add this line if you are shifting a scrollView, as in a chat application
        self.timelineCollectionView.contentInset.top -= keyboardSize.height
        }
    }

สุดท้ายให้เปิดใช้งานการโต้ตอบของผู้ใช้อีกครั้ง (จำไว้ว่าวิธีนี้จะเริ่มขึ้นหลังจากที่คีย์บอร์ดแสดงหรือซ่อน):

func enableUserInteraction()
    {
    UIApplication.shared.endIgnoringInteractionEvents()
    }

1

รหัส Swift 3

var activeField: UITextField?

override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector: #selector(ProfileViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(ProfileViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

func textFieldDidBeginEditing(_ textField: UITextField){
    activeField = textField
}

func textFieldDidEndEditing(_ textField: UITextField){
    activeField = nil
}

func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        if (self.activeField?.frame.origin.y)! >= keyboardSize.height {
            self.view.frame.origin.y = keyboardSize.height - (self.activeField?.frame.origin.y)!
        } else {
            self.view.frame.origin.y = 0
        }
    }
}

func keyboardWillHide(notification: NSNotification) {
    self.view.frame.origin.y = 0
}

1

หากคุณมีฟิลด์ข้อความ 2 ฟิลด์ขึ้นไปบน VC เดียวกันและผู้ใช้แตะที่หนึ่งในนั้นแล้วแตะที่อีกช่องหนึ่งโดยไม่เรียกใช้แป้นพิมพ์ฟังก์ชั่น WillHide มุมมองจะเพิ่มขึ้นหนึ่งครั้งซึ่งไม่จำเป็นเพราะ คุณจะมีแป้นพิมพ์พื้นที่ว่างซึ่งมีความสูงของแป้นพิมพ์และมุมมองโดยใช้รหัสในคำตอบที่ฉันแก้ไข:

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)
}

func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
        self.view.frame.origin.y -= keyboardSize.height
    }
}

func keyboardWillHide(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
        self.view.frame.origin.y += keyboardSize.height
    }
}

ในการแก้ปัญหานี้ให้แทนที่ทั้งสองฟังก์ชั่น "KeyboardWillShow / ซ่อน" เป็น:

func keyboardWillShow(notification: NSNotification) {
 if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
    if view.frame.origin.y == 0{
        self.view.frame.origin.y -= keyboardSize.height
        }
    }
}

func keyboardWillHide(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
        if view.frame.origin.y != 0 {
            self.view.frame.origin.y += keyboardSize.height
        }
    }
}

เกิดอะไรขึ้นถ้าฟิลด์ข้อความของฉันอยู่ด้านบนของมุมมอง .. ? ฉันหมายถึงถ้ามีฟิลด์ข้อความที่มีจุดกำเนิด Y = 0 .. ?? จากนั้นฟิลด์ข้อความกำลังจะขึ้นและฉันไม่เห็นมัน
Saifan Nadaf

1

@ ทางออกของ Boris นั้นดีมาก แต่ในบางครั้งมุมมองอาจเสียหายได้

สำหรับการจัดตำแหน่งที่สมบูรณ์แบบใช้รหัสด้านล่าง

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

ฟังก์ชั่น:

@objc func keyboardWillShow(notification: NSNotification) {        
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
    if self.view.frame.origin.y == 0{
        self.view.frame.origin.y -= keyboardSize.height
    }
}}    

และ,

@objc func keyboardWillHide(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
    if self.view.frame.origin.y != 0{
        self.view.frame.origin.y = 0 
    }
} }

0

วิดีโอสอนนี้ดีที่สุด 7 นาทีและมันก็สมเหตุสมผลดี วิธีแก้ปัญหาง่ายๆเช่นนี้เมื่อคุณมีหลายฟิลด์ข้อความและต้องการให้มุมมองเลื่อนเพื่อย้ายจำนวนพิกเซล "x" เมื่อฟิลด์ข้อความเฉพาะนั้นถูกแตะ

https://youtu.be/VuiPGJOEBH4

เพียงแค่ขั้นตอนเหล่านี้:

- วาง textfields ทั้งหมดของคุณภายใน scrollview ที่ถูก จำกัด ขอบเขตของมุมมอง

- เชื่อมต่อ textfields ทั้งหมดและเลื่อนดูในฐานะผู้ได้รับมอบหมายไปยังตัวควบคุมมุมมอง

เชื่อมต่อฟิลด์ข้อความทั้งหมดและเลื่อนดูด้วย IBOutlet

class ViewController: UIViewController, UITextFieldDelegate {

เพิ่มโปรโตคอล UITextFieldDelegate ให้กับคลาสของคุณ

@IBOutlet var stateAddress: UITextField!
@IBOutlet var zipAddress: UITextField!
@IBOutlet var phoneNumber: UITextField!
@IBOutlet var vetEmailAddress: UITextField!    
@IBOutlet weak var scrollView: UIScrollView!

- เพิ่มวิธี UITextFieldDelegate ให้กับไฟล์ swift ของคุณ:

func textFieldShouldReturn(textField: UITextField) -> Bool {

    textField.resignFirstResponder()
    return true
}


func textFieldDidBeginEditing(textField: UITextField) {

    if (textField == self.stateAddress) {
        scrollView.setContentOffset(CGPointMake(0, 25), animated: true)
    }
    else if (textField == self.zipAddress) {
        scrollView.setContentOffset(CGPointMake(0, 57), animated: true)
    }
    else if (textField == self.phoneNumber) {
        scrollView.setContentOffset(CGPointMake(0, 112), animated: true)
    }
    else if (textField == self.vetEmailAddress) {
        scrollView.setContentOffset(CGPointMake(0, 142), animated: true)
    }
}

func textFieldDidEndEditing(textField: UITextField) {

    scrollView.setContentOffset(CGPointMake(0, 0), animated: true)
}

วิธีแรกเพียงแค่เปิดใช้งานปุ่มย้อนกลับบนแป้นพิมพ์เพื่อยกเลิกแป้นพิมพ์ อย่างที่สองคือเมื่อคุณแตะเข้าไปในฟิลด์ข้อความใด ๆ ก็ตามจากนั้นตั้งค่า y ออฟเซ็ตให้เลื่อนสโครลสโคปของคุณไปไกลแค่ไหน ล่าสุดบอกว่าเมื่อคุณแตะออกจากแป้นพิมพ์ scrollview จะกลับไปที่ตำแหน่งเดิม

ฉันทำให้พิกเซลมุมมองของฉันสมบูรณ์แบบด้วยวิธีนี้!


0

คุณลักษณะนี้สร้างขึ้นใน Ios แต่เราต้องทำจากภายนอก
แทรกรหัสด้านล่าง
* หากต้องการย้ายมุมมองเมื่อ textField อยู่ใต้แป้นพิมพ์
* ไม่ต้องเลื่อนมุมมองเมื่อ textField อยู่เหนือแป้นพิมพ์
* หากต้องการย้ายมุมมองตามความสูงของแป้นพิมพ์เมื่อต้องการ
วิธีนี้ใช้ได้ผลและทดสอบในทุกกรณี

import UIKit

class NamVcc: UIViewController, UITextFieldDelegate
{
    @IBOutlet weak var NamTxtBoxVid: UITextField!

    var VydTxtBoxVar: UITextField!
    var ChkKeyPadDspVar: Bool = false
    var KeyPadHytVal: CGFloat!

    override func viewDidLoad()
    {
        super.viewDidLoad()

        NamTxtBoxVid.delegate = self
    }

    override func viewWillAppear(animated: Bool)
    {
        NSNotificationCenter.defaultCenter().addObserver(self,
            selector: #selector(TdoWenKeyPadVyd(_:)),
            name:UIKeyboardWillShowNotification,
            object: nil);
        NSNotificationCenter.defaultCenter().addObserver(self,
            selector: #selector(TdoWenKeyPadHyd(_:)),
            name:UIKeyboardWillHideNotification,
            object: nil);
    }

    func textFieldDidBeginEditing(TxtBoxPsgVar: UITextField)
    {
        self.VydTxtBoxVar = TxtBoxPsgVar
    }

    func textFieldDidEndEditing(TxtBoxPsgVar: UITextField)
    {
        self.VydTxtBoxVar = nil
    }

    func textFieldShouldReturn(TxtBoxPsgVar: UITextField) -> Bool
    {
        self.VydTxtBoxVar.resignFirstResponder()
        return true
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
    {
        view.endEditing(true)
        super.touchesBegan(touches, withEvent: event)
    }

    func TdoWenKeyPadVyd(NfnPsgVar: NSNotification)
    {
        if(!self.ChkKeyPadDspVar)
        {
            self.KeyPadHytVal = (NfnPsgVar.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().height

            var NonKeyPadAraVar: CGRect = self.view.frame
            NonKeyPadAraVar.size.height -= self.KeyPadHytVal

            let VydTxtBoxCenVal: CGPoint? = VydTxtBoxVar?.frame.origin

            if (!CGRectContainsPoint(NonKeyPadAraVar, VydTxtBoxCenVal!))
            {
                self.ChkKeyPadDspVar = true
                UIView.animateWithDuration(1.0,
                    animations:
                    { self.view.frame.origin.y -= (self.KeyPadHytVal)},
                    completion: nil)
            }
            else
            {
                self.ChkKeyPadDspVar = false
            }
        }

    }

    func TdoWenKeyPadHyd(NfnPsgVar: NSNotification)
    {
        if (self.ChkKeyPadDspVar)
        {
            self.ChkKeyPadDspVar = false
            UIView.animateWithDuration(1.0,
                animations:
                { self.view.frame.origin.y += (self.KeyPadHytVal)},
                completion: nil)
        }
    }

    override func viewDidDisappear(animated: Bool)
    {
        super.viewWillDisappear(animated)
        NSNotificationCenter.defaultCenter().removeObserver(self)
        view.endEditing(true)
        ChkKeyPadDspVar = false
    }
}

| :: | บางครั้งดูจะไม่ทำงานในกรณีนั้นให้ใช้ความสูง +/- 150:

    NonKeyPadAraVar.size.height -= self.KeyPadHytVal + 150

    { self.view.frame.origin.y -= self.KeyPadHytVal  - 150},
                    completion: nil)

    { self.view.frame.origin.y += self.KeyPadHytVal  - 150},
                completion: nil)

0
func keyboardWillShow(notification: NSNotification) {

    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
        self.view.frame.origin.y = self.view.frame.height - (self.view.frame.height + keyboardSize.height)
    }

}

func keyboardWillHide(notification: NSNotification) {
        self.view.frame.origin.y = 0
}

มันจะต้องมีเสถียรภาพมากขึ้น


0
 override func viewWillAppear(animated: Bool)
 {
 super.viewWillAppear(animated)

 NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
 NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)

 }

 // MARK: - keyboard
 func keyboardWillShow(notification: NSNotification) 
{

if let userInfo = notification.userInfo {
if let keyboardSize = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
let contentInsets = self.tblView.contentInset as UIEdgeInsets
self.tblView.contentInset = UIEdgeInsets(top: contentInsets.top, left: contentInsets.left, bottom: keyboardSize.height, right:contentInsets.right)
                    // ...
                } else {
                    // no UIKeyboardFrameBeginUserInfoKey entry in userInfo
                }
            } else {
                // no userInfo dictionary in notification
            }
        }

func keyboardWillHide(notification: NSNotification) 
{
let contentInsets = self.tblView.contentInset as UIEdgeInsets
self.tblView.contentInset = UIEdgeInsets(top: contentInsets.top, left: contentInsets.left, bottom: 0, right:contentInsets.right)
 }

0

ใช้รหัสต่อไปนี้เพื่อดูขึ้นบน UITextField คลิก

func textFieldDidBeginEditing(textField: UITextField) {
    ViewUpanimateMoving(true, upValue: 100)
}
func textFieldDidEndEditing(textField: UITextField) {
    ViewUpanimateMoving(false, upValue: 100)
}
func ViewUpanimateMoving (up:Bool, upValue :CGFloat){
    var durationMovement:NSTimeInterval = 0.3
    var movement:CGFloat = ( up ? -upValue : upValue)
    UIView.beginAnimations( "animateView", context: nil)
    UIView.setAnimationBeginsFromCurrentState(true)
    UIView.setAnimationDuration(durationMovement)
    self.view.frame = CGRectOffset(self.view.frame, 0,  movement)
    UIView.commitAnimations()
}

0

ฉันทำ cocoapod เพื่อทำให้เรื่องนี้ง่ายขึ้น:

https://github.com/xtrinch/KeyboardLayoutHelper

วิธีใช้งาน:

สร้างข้อ จำกัด ด้านล่างของเลย์เอาต์อัตโนมัติโดยให้คลาสของ KeyboardLayoutConstraintในโมดูล KeyboardLayoutHelper และพ็อดจะทำงานที่จำเป็นเพื่อเพิ่มระดับให้คีย์บอร์ดปรากฏขึ้นและหายไป ดูตัวอย่างโครงการเกี่ยวกับตัวอย่างวิธีใช้ (ฉันทำสอง: textFields ภายใน scrollView และ textFields กึ่งกลางแนวตั้งที่มีสองมุมมองพื้นฐาน - ล็อกอินและลงทะเบียน)

ข้อ จำกัด เลย์เอาต์ด้านล่างสามารถเป็นมุมมองคอนเทนเนอร์, ฟิลด์ข้อความตัวเองอะไรก็ได้ที่คุณตั้งชื่อ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.