As I am sure I have said before, one of the frustrations of modern software engineering is that some things you think will be complex turn out to be very simple because the language does it for you with little or no work at all, and other things that you think will be easy (or don’t even realise you will need to do) turn out to be a bit more complicated.
A case in point is the behaviour of the keyboard on iOS when interacting with scrollable components. It never even occurred to me that when the keyboard pops up over a scrollable view that iOS would not simply adjust the dimensions of the view on your behalf. It turns out it doesn’t!
As I was adding a UICollectionView in one of my apps I found that when the keyboard appeared, the bottom row of my collection was hidden behind the keyboard and completely inaccessible to the user. Fortunately in this case the fix is not very complex but it did take a bit of an effort to find it. So for the record here is what I did:
@IBOutlet weak var myCollection: UICollectionView!
override func viewDidLoad() {
let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillHideNotification, object: nil)
notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
}
@objc func adjustForKeyboard(notification: Notification) {
guard let keyboardValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
let keyboardScreenEndFrame = keyboardValue.cgRectValue
let keyboardViewEndFrame = view.convert(keyboardScreenEndFrame, from: view.window)
if notification.name == UIResponder.keyboardWillHideNotification {
myCollection.contentInset = .zero
} else {
if #available(iOS 11.0, *) {
myCollection.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardViewEndFrame.height - view.safeAreaInsets.bottom, right: 0)
} else {
// Fallback on earlier versions
myCollection.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardViewEndFrame.height - bottomLayoutGuide.length, right: 0)
}
}
myCollection.scrollIndicatorInsets = myCollection.contentInset
}
SwiftLearning Swift (Ad)
Leave a Reply