Görünümü yalnızca klavye bir giriş alanını kapattığında yukarı taşıma


152

İPhone için bir giriş ekranı oluşturmaya çalışıyorum. Ekranda bir dizi giriş alanı vardır. Çoğu ekranın üst kısmında, ancak iki alan altta. Kullanıcı ekranın altındaki metni düzenlemeye çalıştığında, klavye açılır ve ekranı kaplar. Bu olduğunda ekranı yukarı taşımak için basit bir çözüm buldum, ancak sonuç, ekran her zaman yukarı hareket ediyor ve kullanıcı bunları düzenlemeye çalıştığında ekranın üst kısmındaki alanlar erişilemiyor.

Ekrana sahip olmanın bir yolu var mı yalnızca alt alanlar düzenlendiğinde hareket etmesini mı?

Burada bulduğum bu kodu kullandım :

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(sender: NSNotification) {
    self.view.frame.origin.y -= 150
}

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

func textFieldDidBeginEditing'i (textField: UITextField!) {} kullanarak hangi
metin alanının

Yanıtlar:


213

Sorununuz bu belgede Apple tarafından iyi bir şekilde açıklanmıştır . Bu sayfadaki (at Listing 4-1) örnek kod tam olarak ihtiyacınız olanı yapar, görünümünüzü yalnızca geçerli düzenleme klavyenin altında olması gerektiğinde kaydırır. Yalnızca gerekli kontrollerinizi bir kaydırma görünümüne koymanız gerekir. Tek sorun, bunun Objective-C olması ve bence Swift'de buna ihtiyacın var .. işte burada:

Bir değişken bildirin

var activeField: UITextField?

sonra bu yöntemleri ekleyin

 func registerForKeyboardNotifications()
{
    //Adding notifies on keyboard appearing
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWasShown:", name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil)
}


func deregisterFromKeyboardNotifications()
{
    //Removing notifies on keyboard appearing
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}

func keyboardWasShown(notification: NSNotification)
{
    //Need to calculate keyboard exact size due to Apple suggestions
    self.scrollView.scrollEnabled = true
    var info : NSDictionary = notification.userInfo!
    var keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().size
    var contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height, 0.0)

    self.scrollView.contentInset = contentInsets
    self.scrollView.scrollIndicatorInsets = contentInsets

    var aRect : CGRect = self.view.frame
    aRect.size.height -= keyboardSize!.height
    if let activeFieldPresent = activeField
    {
        if (!CGRectContainsPoint(aRect, activeField!.frame.origin))
        {
            self.scrollView.scrollRectToVisible(activeField!.frame, animated: true)
        }
    }


}


func keyboardWillBeHidden(notification: NSNotification)
{
    //Once keyboard disappears, restore original positions
    var info : NSDictionary = notification.userInfo!
    var keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().size
    var contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, -keyboardSize!.height, 0.0)
    self.scrollView.contentInset = contentInsets
    self.scrollView.scrollIndicatorInsets = contentInsets
    self.view.endEditing(true)
    self.scrollView.scrollEnabled = false

}

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

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

ViewController'ınızı olarak bildirdiğinizden UITextFieldDelegateve başlatma yöntemlerinizde doğru temsilciler belirlediğinizden emin olun : örn:

self.you_text_field.delegate = self

Ve registerForKeyboardNotificationsviewInit'te ve deregisterFromKeyboardNotificationsçıkışta aramayı unutmayın .

Düzenleme / Güncelleme: Swift 4.2 Sözdizimi

func registerForKeyboardNotifications(){
    //Adding notifies on keyboard appearing
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: NSNotification.Name.UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: NSNotification.Name.UIResponder.keyboardWillHideNotification, object: nil)
}

func deregisterFromKeyboardNotifications(){
    //Removing notifies on keyboard appearing
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIResponder.keyboardWillHideNotification, object: nil)
}

@objc func keyboardWasShown(notification: NSNotification){
    //Need to calculate keyboard exact size due to Apple suggestions
    self.scrollView.isScrollEnabled = true
    var info = notification.userInfo!
    let keyboardSize = (info[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
    let contentInsets : UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardSize!.height, right: 0.0)

    self.scrollView.contentInset = contentInsets
    self.scrollView.scrollIndicatorInsets = contentInsets

    var aRect : CGRect = self.view.frame
    aRect.size.height -= keyboardSize!.height
    if let activeField = self.activeField {
        if (!aRect.contains(activeField.frame.origin)){
            self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
        }
    }
}

@objc func keyboardWillBeHidden(notification: NSNotification){
    //Once keyboard disappears, restore original positions
    var info = notification.userInfo!
    let keyboardSize = (info[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
    let contentInsets : UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: -keyboardSize!.height, right: 0.0)
    self.scrollView.contentInset = contentInsets
    self.scrollView.scrollIndicatorInsets = contentInsets
    self.view.endEditing(true)
    self.scrollView.isScrollEnabled = false
}

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

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

3
ViewDidLoad'da registerForKeyboardNotifications'ı aramanız gerekir, böylece klavyenin ekrandan ne zaman göründüğüne veya kaybolduğuna dair bildirim merkezine bir gözlemci ekleyeceksiniz. Bu bildirimler tetiklendiğinde, keyboardWasShown ve keyboardWillBeHidden yöntemleri çağrılacak ve ardından kaydırma görünümü klavye boyutuna göre hareket edecektir. NotificationCenter hakkında daha ayrıntılı bilgiyi burada bulabilirsiniz: developer.apple.com/library/mac/documentation/Cocoa/Reference/…
Nerkyator

13
Teşekkürler, tam olarak aradığım buydu - elma tarafından önerilen bir çözüm. Ancak benim durumumda zaten görüntülenebilir alanın dışına yayılan bir kaydırma görünümüm vardı. Bu kod, klavye gizlendikten sonra kaydırmayı devre dışı bırakır. "Self.scrollView.scrollEnabled = false" öğesini kaldırdım ve yine de kaydırılmıyor. Benim için işe yarayan şey "self.scrollView.contentInset = UIEdgeInsetsZero;" klavyedeki bu tek
satırWillHide

6
Mükemmel kod. Ama UIKeyboardFrameEndUserInfoKeybunun yerine kullanmalıyım UIKeyboardFrameBeginUserInfoKey, çünkü ikinci dönüş yüksekliği 0'dır. Ve en vuruş noktasını orijin değil dibe değiştirin. if let activeField = self.activeField { var point = activeField.frame.origin point.y += activeField.frame.size.height if (!aRect.contains(point)){ self.scrollView.scrollRectToVisible(activeField.frame, animated: true) } }
Victor Choy

3
@MaX: Bu çalışması gerekir, ancak bir Swift4 çözümünü istiyorsanız kontrol edebilirsiniz bu iOS örneğini gelen Matt Neuburg :) Ben tüm iOS geliştiricilerine öneririz 'ın kitabında
Nerkyator

2
@MaX Bunun sadece hızlı bir 4 şey olup olmadığından emin değilim, ancak görünen şey, textField's didBeginEditingyöntemin yöntem çağrıldıktan SONRA keyboardWillShowçağrılmasıdır. Sonuç olarak, activeFielddeğişken hala sıfırdır, bu da otomatik kaydırmanın olmadığı anlamına gelir. activeField = textFieldÇözümüm , çağrıyı textField shouldBeginEditingyöntemine yerleştirmekti. Bu, aramaların sırası sorununu çözer.
HirdayGupta

152

İşte benim 2 sentim:

Denediniz mi: https://github.com/hackiftekhar/IQKeyboardManager

Swift veya Objective-C'yi kurmak son derece kolay.

Nasıl çalışır:

IQKeyboardManager (Swift): - IQKeyboardManagerSwift, CocoaPods aracılığıyla kullanılabilir, yüklemek için aşağıdaki satırı Podfile'ınıza eklemeniz yeterlidir: (# 236)

pod 'IQKeyboardManagerSwift'

AppDelegate.swift'te, sadece IQKeyboardManagerSwift çerçevesini içe aktarın ve IQKeyboardManager'ı etkinleştirin.

import IQKeyboardManagerSwift

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

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

    IQKeyboardManager.sharedManager().enable = true
    // For Swift 4, use this instead
    // IQKeyboardManager.shared.enable = true


    return true
    }
}

Ve hepsi bu. Kolay!


18
Mükemmel. Bu, varsayılan olarak yerleşik olmalıdır. Olmaması saçma görünüyor.
NathofGod

1
Bu aslında çok saçma, uygulaması çok kolay ve işe yarıyor, ayrıca birden fazla metin alanı arasında geçiş yapmanın kolay bir yolunu
Khoury

birden çok metin alanına geçiş yapmak işe yaramaz mı? metin alanları arasında hareket etmek için tuş takımında ok gösterimi yok.
Arsal

1
Bu harika bir çözümdü, teşekkürler! CocoaPod'ları doğru bir şekilde kurmak benim için tamamen yeni olduğundan biraz çalışma gerektirdi. Bu kurulumu yaptıktan sonra, bunu uygulamak tam anlamıyla 2 satırlık bir koddu ve mükemmel bir şekilde çalıştı. Çok teşekkürler!
IcyBlueRose

5
Swift 4.1 IQKeyboardManager.sharedManager () 'de bu benim için işe yaramadı. Enable = true Şu geçiş yapıldı IQKeyboardManager.shared.enable = true
Rmalmoe

21

Benim için mükemmel çalıştığını bulduğum şey şuydu:

func textFieldDidBeginEditing(textField: UITextField) {
    if textField == email || textField == password {
        animateViewMoving(true, moveValue: 100)
    }
}

func textFieldDidEndEditing(textField: UITextField) {
    if textField == email || textField == password {
        animateViewMoving(false, moveValue: 100)
    }
}

func animateViewMoving (up:Bool, moveValue :CGFloat){
    let movementDuration:NSTimeInterval = 0.3
    let movement:CGFloat = ( up ? -moveValue : moveValue)

    UIView.beginAnimations("animateView", context: nil)
    UIView.setAnimationBeginsFromCurrentState(true)
    UIView.setAnimationDuration(movementDuration)

    self.view.frame = CGRectOffset(self.view.frame, 0, movement)
    UIView.commitAnimations()
}

Ayrıca yükseklik değerlerini de değiştirebilirsiniz. Tüm metin alanları için kullanmak istiyorsanız "if ifadesini" kaldırın.

Bunu, TextView gibi kullanıcı girişi gerektiren tüm kontroller için bile kullanabilirsiniz.


5
Bir UIView çerçevesini doğrudan taşımak harika bir çözüm değildir. Ek olarak bu, bu kullanım durumuna özgü sabit kodlanmış değerleri içerir. İnsanları böyle bir çözümü uygulamamaya ve bunun yerine kabul edilen yanıtta açıklandığı gibi en iyi uygulamalara daha yakın bir şey yapmaya teşvik ederim.
MobileVet

@MobileVet Anlaşıldı, ancak işe yarayan bu.
Tarvo Mäesepp

kodumuza geçmeden harika ayrı mantık
Dilip Jangid

7

Ekranın yalnızca alt alanlar düzenlendiğinde hareket etmesini sağlamanın bir yolu var mı?

Benzer bir sorun vardı ve oldukça basit bir çözüm buldu olmadan bir scrollview kullanarak ve eğer kullanmak yerine keyboardWillShow / Gizle yöntemleri içinde tablolar.

func keyboardWillShow(notification: NSNotification) {
    if bottomText.editing{
        self.view.window?.frame.origin.y = -1 * getKeyboardHeight(notification)
    }
}

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

Bu benim için iyi bir çözümdü çünkü sadece iki metin alanım vardı.

Tüm görünümü yukarı kaydırır: yalnızca belirli metin alanları (alt Metin) düzenlendiğinde

Tüm görünümü aşağı kaydırır: yalnızca görünüm orijinal konumunda olmadığında


5

Klavye sunulduğunda herhangi bir UIView'ı taşımak için bu uzantıyı kullanın.

extension UIView {
    func bindToKeyboard(){
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillChange(_:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
    }

    @objc func keyboardWillChange(_ notification: NSNotification){
        let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
        let curve = notification.userInfo![UIKeyboardAnimationCurveUserInfoKey] as! UInt
        let beginningFrame = (notification.userInfo![UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
        let endFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue

        let deltaY = endFrame.origin.y - beginningFrame.origin.y

        UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIViewKeyframeAnimationOptions(rawValue: curve), animations: {
            self.frame.origin.y += deltaY
        }, completion: nil)
    }
}

Sonra görünümünüzdedidload görünümünüzü klavyeye bağlayın

UiView.bindToKeyboard()

Bu, gerekli olmasa bile görünümü yukarı taşır ve metin alanı görünümün üst kısmındaysa, yukarı çıkacak ve görünmeyecektir. Bu iyi bir çözüm değil.
Shivam Pokhriyal

4

Bunu neden bunun yerine bir UITableViewController'da uygulamıyorsunuz? Klavye, gösterildiğinde hiçbir metin alanını gizlemez.


bu aslında en kolay ve en sağlam yoldur. Ve varsayılan klavye yerine özel bir InputView kullanan kontrollerle bile çalışır (UIKeyboard bildirimleri bunlar için çalışmaz)
Radu Simionescu

1
Tablo görünümü gömülü ise ("sayfanın tamamı" olmaktan ziyade) dikkatli olmanız gereken bir sorun vardır. Herkes bu tarafından takıldı için çözüm gibi mesajların açıklanmıştır bu ve bu . Umarım bu, "tüm Apple'daki en aptalca sorunla" uğraşan birine yardımcı olur!
Fattie

3

Swift 4 (** güncellendi ) uzantı ile **

  1. düğmeleri tek bir kaba ekleyin
  2. IBOutlet containerBtmConstrain ile kabın alt kısıtlamasını bağlayın
  3. inViewDidLoad

    self.containerDependOnKeyboardBottomConstrain = containerBtmConstrain
    self.watchForKeyboard() 
    
  4. aşağıdaki uzantıyı ekleyin

    import UIKit
    
    private var xoAssociationKeyForBottomConstrainInVC: UInt8 = 0
    
    extension UIViewController {
    
        var containerDependOnKeyboardBottomConstrain :NSLayoutConstraint! {
            get {
                return objc_getAssociatedObject(self, &xoAssociationKeyForBottomConstrainInVC) as? NSLayoutConstraint
            }
            set(newValue) {
                objc_setAssociatedObject(self, &xoAssociationKeyForBottomConstrainInVC, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
            }
        }
    
        func watchForKeyboard() {
            NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWasShown(notification:)), name:UIResponder.keyboardWillShowNotification, object: nil);
            NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(notification:)), name:UIResponder.keyboardWillHideNotification, object: nil);
        }
    
        @objc func keyboardWasShown(notification: NSNotification) {
            let info = notification.userInfo!
            guard let keyboardFrame: CGRect = (info[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else {
              return
            }
    
            UIView.animate(withDuration: 0.3, animations: { () -> Void in
                self.containerDependOnKeyboardBottomConstrain.constant = -keyboardFrame.height
                self.view.layoutIfNeeded()
            })
        }
    
        @objc func keyboardWillHide(notification: NSNotification) {
            UIView.animate(withDuration: 0.3, animations: { () -> Void in
                self.containerDependOnKeyboardBottomConstrain.constant = 0
                self.view.layoutIfNeeded()
            })
        }
    }
    

1
Teşekkürler dostum. Her şey doğru anahtarla ilgili. UIKeyboardFrameBeginUserInfoKey kullanıyordum ve şimdi UIKeyboardFrameEndUserInfoKey kullanarak bunu incelikle ele alıyorum.
Felipe

2

Kabul edilen cevabın biçimlendirilmesiyle ilgili birkaç sorunu olan SwiftLint'i kullanıyorum. Özellikle:

kolondan önce boşluk yok, kuvvet atama yok, UIEdgeInsetMake yerine UIEdgeInset'i tercih edin (üst: vb ...

işte Swift 3 için güncellemeler

func registerForKeyboardNotifications() {
    //Adding notifies on keyboard appearing
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

func deregisterFromKeyboardNotifications() {
    //Removing notifies on keyboard appearing
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

func keyboardWasShown(notification: NSNotification) {
    //Need to calculate keyboard exact size due to Apple suggestions
    scrollView?.isScrollEnabled = true
    var info = notification.userInfo!
    if let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size {
        let contentInsets: UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardSize.height, right: 0.0)

        scrollView?.contentInset = contentInsets
        scrollView?.scrollIndicatorInsets = contentInsets

        var aRect: CGRect = self.view.frame
        aRect.size.height -= keyboardSize.height
        if let activeField = self.activeField {
            if !aRect.contains(activeField.frame.origin) {
                self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
            }
        }
    }
}

func keyboardWillBeHidden(notification: NSNotification) {
    //Once keyboard disappears, restore original positions
    var info = notification.userInfo!
    if let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size {
        let contentInsets: UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: -keyboardSize.height, right: 0.0)
        scrollView?.contentInset = contentInsets
        scrollView?.scrollIndicatorInsets = contentInsets
    }

    view.endEditing(true)
    scrollView?.isScrollEnabled = false
}

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

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

1

Sanırım bu madde yanlış:

if (!CGRectContainsPoint(aRect, activeField!.frame.origin))

ActiveField'ın orijini klavyenin çok üstünde olsa da maxY olmayabilir ...

ActiveField için bir 'max' noktası oluşturur ve bunun Rect klavyesinde olup olmadığını kontrol ederdim.


0

İşte Apple tarafından sağlanan belgeleri ve önceki yayınları okuduktan sonraki sürümüm. Fark ettiğim bir şey, textView'ın klavye tarafından kapatıldığında işlenmediğiydi. Maalesef, Apple'ın dokümantasyonu çalışmaz çünkü, her ne sebeple olursa olsun, klavye textViewDidBeginEditing çağrıldıktan SONRA çağrılır. Bunu, klavyenin görüntülenip görüntülenmediğini VE bir textView veya textField'in düzenlenip düzenlenmediğini kontrol eden merkezi bir yöntemi arayarak hallettim. Bu şekilde, işlem yalnızca HER İKİSİ koşul mevcut olduğunda çalıştırılır.

TextViews ile ilgili diğer bir nokta da, yüksekliğinin, klavye textView'ün altını kırpacak şekilde olabileceği ve üst-Sol noktası görünümdeyken ayarlanamayacağıdır. Bu yüzden yazdığım kod aslında herhangi bir textView veya textField'in ekran referanslı Alt-Sol noktasını alıyor ve sunulan klavyenin ekran referanslı koordinatlarına girip girmediğini görüyor ve bu da klavyenin bir kısmını kapsadığını ima ediyor.

let aRect : CGRect = scrollView.convertRect(activeFieldRect!, toView: nil)
    if (CGRectContainsPoint(keyboardRect!, CGPointMake(aRect.origin.x, aRect.maxY))) {
        // scroll textView/textField into view
    }

Bir gezinme denetleyicisi kullanıyorsanız, alt sınıf, ayrıca girişler için kaydırma görünümü otomatik ayarını yanlış olarak ayarlar.

self.automaticallyAdjustsScrollViewInsets = false

Her textView ve textField'da işlem için temsilciler ayarlamak için gezinir

    for view in self.view.subviews {
        if view is UITextView {
            let tv = view as! UITextView
            tv.delegate = self
        } else if view is UITextField {
            let tf = view as! UITextField
            tf.delegate = self
        }
    }

Temel sınıfınızı sonuçlar için burada oluşturulan alt sınıfa ayarlamanız yeterlidir.

import UIKit

class ScrollingFormViewController: UIViewController, UITextViewDelegate, UITextFieldDelegate {

var activeFieldRect: CGRect?
var keyboardRect: CGRect?
var scrollView: UIScrollView!

override func viewDidLoad() {

    self.automaticallyAdjustsScrollViewInsets = false

    super.viewDidLoad()

    // Do any additional setup after loading the view.
    self.registerForKeyboardNotifications()
    for view in self.view.subviews {
        if view is UITextView {
            let tv = view as! UITextView
            tv.delegate = self
        } else if view is UITextField {
            let tf = view as! UITextField
            tf.delegate = self
        }
    }
    scrollView = UIScrollView(frame: self.view.frame)
    scrollView.scrollEnabled = false
    scrollView.showsVerticalScrollIndicator = false
    scrollView.showsHorizontalScrollIndicator = false
    scrollView.addSubview(self.view)
    self.view = scrollView
}

override func viewDidLayoutSubviews() {
    scrollView.sizeToFit()
    scrollView.contentSize = scrollView.frame.size
    super.viewDidLayoutSubviews()
}

deinit {
    self.deregisterFromKeyboardNotifications()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


func registerForKeyboardNotifications()
{
    //Adding notifies on keyboard appearing
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ScrollingFormViewController.keyboardWasShown), name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ScrollingFormViewController.keyboardWillBeHidden), name: UIKeyboardWillHideNotification, object: nil)
}


func deregisterFromKeyboardNotifications()
{
    //Removing notifies on keyboard appearing
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}

func keyboardWasShown(notification: NSNotification)
{
    let info : NSDictionary = notification.userInfo!
    keyboardRect = (info[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue()
    adjustForKeyboard()
}


func keyboardWillBeHidden(notification: NSNotification)
{
    keyboardRect = nil
    adjustForKeyboard()
}

func adjustForKeyboard() {
    if keyboardRect != nil && activeFieldRect != nil {
        let aRect : CGRect = scrollView.convertRect(activeFieldRect!, toView: nil)
        if (CGRectContainsPoint(keyboardRect!, CGPointMake(aRect.origin.x, aRect.maxY)))
        {
            scrollView.scrollEnabled = true
            let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardRect!.size.height, 0.0)
            scrollView.contentInset = contentInsets
            scrollView.scrollIndicatorInsets = contentInsets
            scrollView.scrollRectToVisible(activeFieldRect!, animated: true)
        }
    } else {
        let contentInsets : UIEdgeInsets = UIEdgeInsetsZero
        scrollView.contentInset = contentInsets
        scrollView.scrollIndicatorInsets = contentInsets
        scrollView.scrollEnabled = false
    }
}

func textViewDidBeginEditing(textView: UITextView) {
    activeFieldRect = textView.frame
    adjustForKeyboard()
}

func textViewDidEndEditing(textView: UITextView) {
    activeFieldRect = nil
    adjustForKeyboard()
}

func textFieldDidBeginEditing(textField: UITextField)
{
    activeFieldRect = textField.frame
    adjustForKeyboard()
}

func textFieldDidEndEditing(textField: UITextField)
{
    activeFieldRect = nil
    adjustForKeyboard()
}

}

0

Şimdiden harika cevaplar veriliyor ancak bu durumla başa çıkmanın farklı bir yolu ( Swift 3x kullanarak ):

Her şeyden önce aşağıdaki yöntemi çağırın viewWillAppear()

func registerForKeyboardNotifications() {

NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWasShown), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillBeHidden), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

}

Şimdi birini almak IBOutletarasında UIView, aramalarınızdan bireyin üst kısıtlamalar UIViewcontrollerböyle: (Burada UIViewbir subview olduğunu UIScrollViewsen sahip olması gerektiğini yollarla bir UIScrollViewbütün için senin subViews)

@IBOutlet weak var loginViewTopConstraint: NSLayoutConstraint!

Ve aşağıdaki gibi başka bir değişken ve bir temsilci ekleyin, yani UITextFieldDelegate:

var activeTextField = UITextField() //This is to keep the reference of UITextField currently active

Bundan sonra işte büyülü kısım, bunu aşağıdaki pasajı yapıştırın :

func keyboardWasShown(_ notification: Notification) {

let keyboardInfo  = notification.userInfo as NSDictionary?

//print(keyboardInfo!)

let keyboardFrameEnd: NSValue? = (keyboardInfo?.value(forKey: UIKeyboardFrameEndUserInfoKey) as? NSValue)

let keyboardFrameEndRect: CGRect? = keyboardFrameEnd?.cgRectValue


if activeTextField.frame.origin.y + activeTextField.frame.size.height + 10 > (keyboardFrameEndRect?.origin.y)! {

    UIView.animate(withDuration: 0.3, delay: 0, options: .transitionFlipFromTop, animations: {() -> Void in

        //code with animation

        //Print some stuff to know what is actually happening
        //print(self.activeTextField.frame.origin.y)
        //print(self.activeTextField.frame.size.height)
        //print(self.activeTextField.frame.size.height)

        self.loginViewTopConstraint.constant = -(self.activeTextField.frame.origin.y + self.activeTextField.frame.size.height - (keyboardFrameEndRect?.origin.y)!) - 30.0

        self.view.layoutIfNeeded()

    }, completion: {(_ finished: Bool) -> Void in
        //code for completion

    })
}
}

func keyboardWillBeHidden(_ notification: Notification) {

UIView.animate(withDuration: 0.3, animations: {() -> Void in

    self.loginViewTopConstraint.constant = self.view.frame.origin.y
    self.view.layoutIfNeeded()

})
}

//MARK: textfield delegates
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
    activeTextField = textField
    return true
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {

           switch textField {
    case YOUR_TEXTFIELD_ONE:
        YOUR_TEXTFIELD_TWO.becomeFirstResponder()
        break
    case YOUR_TEXTFIELD_TWO:
        YOUR_TEXTFIELD_THREE.becomeFirstResponder()
        break
    default:
        textField.resignFirstResponder()
        break
    }
    return true
}

Şimdi son pasaj:

//Remove Keyboard Observers
override func viewWillDisappear(_ animated: Bool) {

NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardDidShow, object: nil)

NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

Tüm için atama delegelere unutmayın UITextFieldsUIStoryboard

İyi şanslar!


0

Swift 3 sözdizimi:

func textFieldDidBeginEditing(_ textField: UITextField) {
    // add if for some desired textfields
        animateViewMoving(up: true, moveValue: 100)
}

func textFieldDidEndEditing(_ textField: UITextField) {
    // add if for some desired textfields
        animateViewMoving(up: false, moveValue: 100)
}

func animateViewMoving (up:Bool, moveValue :CGFloat){
     textFieldDidEndEditing(_ textField: UITextField) {

    let movementDuration:TimeInterval = 0.5

    let movement:CGFloat = ( up ? -moveValue : moveValue)

    UIView.beginAnimations("animateView", context: nil)

    UIView.setAnimationBeginsFromCurrentState(true)

    UIView.setAnimationDuration(movementDuration)

    self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement)

    UIView.commitAnimations()
}

bu, istediğinizi elde etmek için güzel bir yöntemdir, belirli metin alanları için "eğer" koşulları ekleyebilirsiniz, ancak bu tür herkes için işe yarar ... Umarım herkes için yararlı olabilir


0

Öncelikle, aktif UITextField'ınızı tanımlamak için bir değişken tanımlayın.

Aşama 1:-

Gibi var activeTextField: UITextField ?

Adım 2: - Bundan sonra bu iki satırı viewDidLoad'a ekleyin.

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)

Aşama 3:-

Şimdi bu iki yöntemi denetleyici sınıfınızda tanımlayın.

func keyboardWillShow(_ notification: NSNotification) {

    self.scrollView.isScrollEnabled = true
    var info = notification.userInfo!
    let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
    let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height, 0.0)

    self.scrollView.contentInset = contentInsets
    self.scrollView.scrollIndicatorInsets = contentInsets

    var aRect : CGRect = self.view.frame
    aRect.size.height -= keyboardSize!.height
    if let activeField = self.activeField {
        if (!aRect.contains(activeField.frame.origin)){
            self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
        }
    }
}


func keyboardWillHide(_ notification: NSNotification) {

    let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, 0.0, 0.0)
    self.scrollView.contentInset = contentInsets
    self.scrollView.scrollIndicatorInsets = contentInsets
    self.view.endEditing(true)
    self.scrollView.isScrollEnabled = true
}


func textFieldDidBeginEditing(_ textField: UITextField){

    activeField = textField
}

func textFieldDidEndEditing(_ textField: UITextField){

    activeField = nil
}

0

hızlı için 4.2.

Bu, herhangi bir form için geçerli olacaktır. Kaydırma görünümüne gerek yok. delege ayarlamayı unutmayın.

Uitextfield'ın bir varyasyonunu yapın

var clickedTextField = UITextField()

Viewdid yükünüzde

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

Tıklanan metin alanını bilin. Muhtemelen tüm ekranda metin alanlarınız var.

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

Klavyenin metin alanını kapatıp kapatmadığını kontrol edin.

@objc func keyboardWillShow(sender: NSNotification,_ textField : UITextField) {
    if let keyboardSize = (sender.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {

        if clickedTextField.frame.origin.y > keyboardSize.origin.y {
            self.view.frame.origin.y = keyboardSize.origin.y - clickedTextField.center.y - 20
        }
    }
}

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

Klavyeyi kapatmaya dön

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

GÜNCELLEME: NSNotification.Name.UIKeyboardWillShow ve NSNotification.Name.UIKeyboardWillHide, sırasıyla UIResponder.keyboardWillShowNotification ve UIResponder.keyboardWillHideNotification olarak yeniden adlandırılır.


Temsilciyi bu kod üzerinde nasıl ayarlarsınız lütfen?
David_2877

viewController'ınızda bir usernameTextfield çıkışı aldığınızı varsayalım.
ViewDidLoad'da

Bilgi için teşekkürler. Bunu harfine kadar takip ettim ve klavyeyi kaldırmıyor. Kodla oynadım, ancak çalışmasını sağlayamıyorum. İOS 14 ve Xcode 12 kullanıyorum. Teşekkürler.
David_2877

Uiviewcontroller için UITextViewDelegate protokolünü onayladınız mı? bu çalışmıyorsa, "IQKeyboardManager" kitaplığını kullanabilirsiniz.
rupesh45

0

Swift : Bunu, hangi textField'ın sunulduğunu kontrol ederek yapabilirsiniz.

@objc func keyboardWillShow(notification: NSNotification) {
    if self.textField.isFirstResponder == true {
        self.view.frame.origin.y -= 150
     }
}

@objc func keyboardWillHide(notification: NSNotification){
    if self.textField.isFirstResponder == true {
       self.view.frame.origin.y += 150
    }
}

-1

Bu kod, düzenlemekte olduğunuz metin alanını yukarı taşır, böylece onu Swift 3'te görüntüleyebilirsiniz, bu yanıt için ayrıca görünümünüzü bir UITextFieldDelegate yapmanız gerekir:

var moveValue: CGFloat!
var moved: Bool = false
var activeTextField = UITextField()

func textFieldDidBeginEditing(_ textField: UITextField) {
    self.activeTextField = textField
}
func textFieldDidEndEditing(_ textField: UITextField) {
    if moved == true{
    self.animateViewMoving(up: false, moveValue: moveValue )
        moved = false
    }
}
func animateViewMoving (up:Bool, moveValue :CGFloat){
    let movementDuration:TimeInterval = 0.3
    let movement:CGFloat = ( up ? -moveValue : moveValue)

    UIView.beginAnimations("animateView", context: nil)
    UIView.setAnimationBeginsFromCurrentState(true)
    UIView.setAnimationDuration(movementDuration)

    self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement)
    UIView.commitAnimations()
}

Ve sonra viewDidLoad'da:

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

Hangi çağrılar (viewDidLoad dışında):

func keyboardWillShow(notification: Notification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        let keyboardHeight = keyboardSize.height
        if (view.frame.size.height-self.activeTextField.frame.origin.y) - self.activeTextField.frame.size.height < keyboardHeight{
            moveValue = keyboardHeight - ((view.frame.size.height-self.activeTextField.frame.origin.y) - self.activeTextField.frame.size.height)
            self.animateViewMoving(up: true, moveValue: moveValue )
            moved = true
        }
    }
}

-1

Hızlı 3

@IBOutlet var scrollView: UIScrollView!
@IBOutlet var edtEmail: UITextField!
@IBOutlet var bottomTextfieldConstrain: NSLayoutConstraint! // <- this guy is the constrain that connect the bottom of textField to lower object or bottom of page!

 @IBAction func edtEmailEditingDidBegin(_ sender: Any) { 
        self.bottomTextfieldConstrain.constant = 200
        let point = CGPoint(x: 0, y: 200)
        scrollView.contentOffset = point
    }

@IBAction func edtEmailEditingDidEnd(_ sender: Any) { 
    self.bottomTextfieldConstrain.constant = 50
}

-1

Kabul edilen cevaplayıcı neredeyse mükemmel. Ama UIKeyboardFrameEndUserInfoKeybunun yerine kullanmalıyım UIKeyboardFrameBeginUserInfoKey,çünkü ikincisi keyborad yüksekliğini 0 döndürüyor. Ve en vuruş noktasını orijin değil dibe değiştirin.

    var aRect : CGRect = self.view.frame
    aRect.size.height -= keyboardSize!.height
    if let activeField = self.activeField {
        var point = activeField.frame.origin
        point.y += activeField.frame.size.height
        if (!aRect.contains(point)){
            self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
        }
    }

-1

Swift 4 Çözümümü güncelledi

klavye gösterme / gizleme üzerinde kısıtlama animasyonu ile keyfini çıkarın.

import Foundation
import UIKit

class PhoneController: UIViewController, UITextFieldDelegate{

    var phoneLayoutYConstraint: NSLayoutConstraint?

    override func viewDidLoad() {

        super.viewDidLoad()

        view.backgroundColor = .white

        NotificationCenter.default.addObserver(self, selector: #selector(handleKeyBoardNotification(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(handleKeyBoardNotification(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
        phoneField.delegate = self

        view.addSubview(phoneField)

        NSLayoutConstraint.activate([phoneField.heightAnchor.constraint(equalToConstant: 50),
                                     phoneField.centerXAnchor.constraint(equalTo: view.centerXAnchor),
                                     phoneField.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
                                     phoneField.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20)])

        phoneLayoutYConstraint = NSLayoutConstraint(item: phoneField, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0)
        phoneLayoutYConstraint?.isActive = true

    }

    let phoneField: UITextField = {
        let text = UITextField()
        text.translatesAutoresizingMaskIntoConstraints = false
        text.keyboardType = .numberPad
        text.font = UIFont.systemFont(ofSize: 30)
        text.layer.cornerRadius = 5.0
        text.layer.masksToBounds = true
        text.layer.borderColor = UIColor.darkGray.cgColor
        text.layer.borderWidth = 2.0

        return text
    }()


    override func viewDidDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        NotificationCenter.default.removeObserver(self)
    }

    func textFieldDidBeginEditing(_ textField: UITextField) {

    }


    func textFieldDidEndEditing(_ textField: UITextField) {

    }

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


   @objc func handleKeyBoardNotification(_ notification: NSNotification) {

        if let info = notification.userInfo {

            let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
            let isKeyBoardShowing = notification.name == NSNotification.Name.UIKeyboardWillShow

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


            phoneLayoutYConstraint?.constant = isKeyBoardShowing ? -keyboardSize!.height : 0

            UIView.animate(withDuration: 0, delay: 0, options: .curveEaseOut, animations: {
                self.view.layoutIfNeeded()
            }, completion: { (boo) in

            })

        }
    }

}

-1

Swift 4

UITextFieldAnimasyon İle Klavye İle Kolayca Yukarı Aşağı Hareket Edebilirsiniz

görüntü açıklamasını buraya girin

import UIKit

class ViewController: UIViewController {

    @IBOutlet var textField: UITextField!

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

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        textField.resignFirstResponder()
    }

    @objc func keyboardWillChange(notification: NSNotification) {

        let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
        let curve = notification.userInfo![UIKeyboardAnimationCurveUserInfoKey] as! UInt
        let curFrame = (notification.userInfo![UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
        let targetFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
        let deltaY = targetFrame.origin.y - curFrame.origin.y

        UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIViewKeyframeAnimationOptions(rawValue: curve), animations: {
            self.textField.frame.origin.y+=deltaY

        },completion: nil)
    }

Yine, ihtiyaç olmadığında bile gereksiz yere görüntüyü yukarı itecek bir çözüm. Lütfen yanıtınızı iyileştirin, yanıltıcı
Shivam Pokhriyal

-1

Swift 4.2

Çözümüm, görünümü (dikey olarak) bir UITextField , konumu klavyenin altındaysa .

Adım 1: Yeni bir swift dosyası oluşturun ve UIViewWithKeyboardsınıfı kopyalayıp yapıştırın .
Adım 2: Arayüz Oluşturucu'da bunu en iyileriniz için Özel Sınıf olarak ayarlayın UIView.

import UIKit

class UIViewWithKeyboard: UIView {
    @IBInspectable var offsetMultiplier: CGFloat = 0.75
    private var keyboardHeight = 0 as CGFloat
    private weak var activeTextField: UITextField?
    override func awakeFromNib() {
        super.awakeFromNib()
        NotificationCenter.default.addObserver(self, selector: #selector(UIViewWithKeyboard.textDidBeginEditing),
                                               name: UITextField.textDidBeginEditingNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(UIViewWithKeyboard.keyboardWillShow),
                                               name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(UIViewWithKeyboard.keyboardWillHide),
                                               name: UIResponder.keyboardWillHideNotification, object: nil)
    }

    @objc func textDidBeginEditing(_ notification: NSNotification) {
        self.activeTextField = notification.object as? UITextField
    }

    @objc func keyboardWillShow(_ notification: Notification) {
        if let frameValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
            keyboardHeight = frameValue.cgRectValue.size.height
            if let textField = self.activeTextField {
                let offset = textField.frame.maxY < frame.maxY - keyboardHeight ? 0
                           : textField.frame.maxY - (frame.maxY - keyboardHeight) * offsetMultiplier
                self.setView(offset: offset)
            }
        }
    }

    @objc func keyboardWillHide(_ notification: NSNotification) {
        self.setView(offset: 0)
    }

    func setView(offset: CGFloat) {
        UIView.animate(withDuration: 0.25) {
            self.bounds.origin.y = offset
        }
    }
}

-1

Hızlı 4.2 için yeniden yazıldı

ViewDidLoad'da ..

 NotificationCenter.default.addObserver(self, selector: #selector(trailViewController.keyboardWasShown), name: UIResponder.keyboardWillShowNotification, object: nil)
 NotificationCenter.default.addObserver(self, selector: #selector(trailViewController.keyboardWillBeHidden), name: UIResponder.keyboardWillHideNotification, object: nil)

Kalan İşlevler

func registerForKeyboardNotifications(){
    //Adding notifies on keyboard appearing
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}

func deregisterFromKeyboardNotifications(){
    //Removing notifies on keyboard appearing
    NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
}

@objc func keyboardWasShown(notification: NSNotification){
    //Need to calculate keyboard exact size due to Apple suggestions
    self.scrollView.isScrollEnabled = true
    var info = notification.userInfo!
    let keyboardSize = (info[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
    let contentInsets : UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardSize!.height, right: 0.0)

    self.scrollView.contentInset = contentInsets
    self.scrollView.scrollIndicatorInsets = contentInsets

    var aRect : CGRect = self.view.frame
    aRect.size.height -= keyboardSize!.height
    if let activeField = self.activeField {
        if (!aRect.contains(activeField.frame.origin)){
            self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
        }
    }
}

@objc func keyboardWillBeHidden(notification: NSNotification){
    //Once keyboard disappears, restore original positions
    var info = notification.userInfo!
    let keyboardSize = (info[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
    let contentInsets : UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: -keyboardSize!.height, right: 0.0)
    self.scrollView.contentInset = contentInsets
    self.scrollView.scrollIndicatorInsets = contentInsets
    self.view.endEditing(true)
    self.scrollView.isScrollEnabled = false
}

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

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

-2

"Swift'de yeni olduğumu söylemeyi unuttum :( Bunu kontrol etmek için doğru sözdizimi nedir? (Bu işlevde alan adını nasıl alırım?)"

Tamam . Önce UITextFieldDelegate protokolünü onaylayın

class YourClass:UITextFieldDelegate

Ardından işlevi uygulayın

func textFieldDidBeginEditing(textField: UITextField!) {

    if textField == txtOne
    {
        println("TextOne")
    }
    if textField == txtTwo
    {
        println("TextTwo")
    }
}

Doğru yaklaşımın bir kaydırma görünümü kullanmak ve kaydırma görünümünün içinde yukarı / aşağı kaydırılması gereken görünümü yerleştirmek ve klavye olaylarını buna göre işlemek olduğuna dikkat etmelisiniz.


-5

Swift 4.2 için

Bu kod, belirli bir cihaz ekran boyutu için çerçevenin Y ekseni momentini kontrol etmenizi sağlar.

Not: Bu kod, çerçeveyi TextField konumuna göre akıllıca hareket ettirmeyecektir.

UIDevice için bir uzantı oluşturun

extension UIDevice {
    enum ScreenType: String {
        case iPhone4_4S = "iPhone 4 or iPhone 4s"
        case iPhones_5_5s_5c_SE = "iPhone 5, iPhone 5s, iPhone 5c or iPhone SE"
        case iPhones_6_6s_7_8 = "iPhone 6, iPhone 6s, iPhone 7 or iPhone 8"
        case iPhones_6Plus_6sPlus_7Plus_8Plus = "iPhone 6 Plus, iPhone 6s Plus, iPhone 7 Plus or iPhone 8 Plus"
        case iPhoneX_Xs = "iPhone X, iPhone Xs"
        case iPhoneXR = "iPhone XR"
        case iPhoneXSMax = "iPhone Xs Max"
        case unknown
    }
    var screenType: ScreenType {
        switch UIScreen.main.nativeBounds.height {
        case 960:
            return .iPhone4_4S
        case 1136:
            return .iPhones_5_5s_5c_SE
        case 1334:
            return .iPhones_6_6s_7_8
        case 1920, 2208:
            return .iPhones_6Plus_6sPlus_7Plus_8Plus
        case 1792:
            return .iPhoneXR
        case 2436:
            return .iPhoneX_Xs
        case 2688:
            return .iPhoneXSMax
        default:
            return .unknown
        }
    }
}

ViewDidLoad üzerine NotificationObserver ekle

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

Seçici

@objc func keyboardWillShow(notification: NSNotification) {
    if ((notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue) != nil {
        if self.view.frame.origin.y == 0 {
            switch (UIDevice.current.screenType.rawValue) {
            case (UIDevice.ScreenType.iPhones_5_5s_5c_SE.rawValue):
                self.view.frame.origin.y -= 210
            case (UIDevice.ScreenType.iPhones_6_6s_7_8.rawValue):
                self.view.frame.origin.y -= 110
            case (UIDevice.ScreenType.iPhones_6Plus_6sPlus_7Plus_8Plus.rawValue):
                self.view.frame.origin.y -= 80
            case (UIDevice.ScreenType.iPhoneX_Xs.rawValue):
                self.view.frame.origin.y -= 70
            case (UIDevice.ScreenType.iPhoneXR.rawValue):
                self.view.frame.origin.y -= 70
            case (UIDevice.ScreenType.iPhoneXSMax.rawValue):
                self.view.frame.origin.y -= 70
            default:
                self.view.frame.origin.y -= 150
            }
        }
    }
}

@objc func keyboardWillHide(notification: NSNotification) {
    if ((notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue) != nil {
        if self.view.frame.origin.y != 0 {
            switch (UIDevice.current.screenType.rawValue) {
            case (UIDevice.ScreenType.iPhones_5_5s_5c_SE.rawValue):
                self.view.frame.origin.y += 210
            case (UIDevice.ScreenType.iPhones_6_6s_7_8.rawValue):
                self.view.frame.origin.y += 110
            case (UIDevice.ScreenType.iPhones_6Plus_6sPlus_7Plus_8Plus.rawValue):
                self.view.frame.origin.y += 80
            case (UIDevice.ScreenType.iPhoneX_Xs.rawValue):
                self.view.frame.origin.y += 70
            case (UIDevice.ScreenType.iPhoneXR.rawValue):
                self.view.frame.origin.y += 70
            case (UIDevice.ScreenType.iPhoneXSMax.rawValue):
                self.view.frame.origin.y += 70
            default:
                self.view.frame.origin.y += 150
            }
        }
    }
}

1
Genel olarak, değişmeye devam ettikçe cihaza özgü türleri ve sabit kod yerleşimiyle ilgili boyutları kullanmanın kötü ve oldukça maliyetli bir yaklaşım olduğunu söyleyebilirim.
Johan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.