Merge branch 'nt/attachment-keyboard-fixes' into release/2.42.0

This commit is contained in:
Nora Trapp 2019-08-10 12:42:31 -07:00
commit 86ef4b032e
7 changed files with 57 additions and 64 deletions

View File

@ -15,20 +15,16 @@ protocol AttachmentFormatPickerDelegate: class {
class AttachmentFormatPickerView: UICollectionView {
weak var attachmentFormatPickerDelegate: AttachmentFormatPickerDelegate?
private var itemSize: CGSize {
return CGSize(width: frame.height, height: frame.height)
var itemSize: CGSize = .zero {
didSet {
guard oldValue != itemSize else { return }
updateLayout()
}
}
private let collectionViewFlowLayout = UICollectionViewFlowLayout()
private var photoCapture: PhotoCapture?
override var bounds: CGRect {
didSet {
guard oldValue != bounds else { return }
updateLayout()
}
}
init() {
super.init(frame: .zero, collectionViewLayout: collectionViewFlowLayout)
@ -68,19 +64,15 @@ class AttachmentFormatPickerView: UICollectionView {
photoCapture = nil
}
func orientationDidChange() {
updateLayout()
}
private func updateLayout() {
AssertIsOnMainThread()
guard frame.height > 0 else { return }
guard itemSize.height > 0, itemSize.width > 0 else { return }
// The items should always expand to fit the height of the collection view.
// We'll always just have one row of items.
collectionViewFlowLayout.itemSize = itemSize
collectionViewFlowLayout.invalidateLayout()
reloadData()
}
required init?(coder aDecoder: NSCoder) {

View File

@ -144,7 +144,8 @@ class AttachmentKeyboard: CustomKeyboard {
override func wasPresented() {
super.wasPresented()
checkPermissionsAndLayout()
checkPermissions()
updateItemSizes()
}
override func wasDismissed() {
@ -156,22 +157,25 @@ class AttachmentKeyboard: CustomKeyboard {
override func orientationDidChange() {
super.orientationDidChange()
recentPhotosCollectionView.orientationDidChange()
attachmentFormatPickerView.orientationDidChange()
updateItemSizes()
}
func checkPermissionsAndLayout() {
func updateItemSizes() {
// The items should always expand to fit the height of their collection view.
// We'll always just have one row of items.
recentPhotosCollectionView.itemSize = CGSize(square: recentPhotosCollectionView.height())
attachmentFormatPickerView.itemSize = CGSize(square: attachmentFormatPickerView.height())
}
func checkPermissions() {
switch mediaLibraryAuthorizationStatus {
case .authorized:
showRecentPhotos()
case .denied, .restricted:
showRecentPhotosError()
case .notDetermined:
PHPhotoLibrary.requestAuthorization { status in
DispatchQueue.main.async {
if status == .authorized { self.recentPhotosCollectionView.permissionChanged() }
self.checkPermissionsAndLayout()
}
PHPhotoLibrary.requestAuthorization { _ in
DispatchQueue.main.async { self.checkPermissions() }
}
@unknown default:
showRecentPhotosError()

View File

@ -45,8 +45,11 @@ class RecentPhotosCollectionView: UICollectionView {
private lazy var collection = photoLibrary.defaultPhotoCollection()
private lazy var collectionContents = collection.contents(ascending: false, limit: maxRecentPhotos)
private var itemSize: CGSize {
return CGSize(width: frame.height, height: frame.height)
var itemSize: CGSize = .zero {
didSet {
guard oldValue != itemSize else { return }
updateLayout()
}
}
private var photoMediaSize: PhotoMediaSize {
@ -57,13 +60,6 @@ class RecentPhotosCollectionView: UICollectionView {
private let collectionViewFlowLayout = UICollectionViewFlowLayout()
override var bounds: CGRect {
didSet {
guard oldValue != bounds else { return }
updateLayout()
}
}
init() {
super.init(frame: .zero, collectionViewLayout: collectionViewFlowLayout)
@ -83,26 +79,17 @@ class RecentPhotosCollectionView: UICollectionView {
updateLayout()
}
func permissionChanged() {
guard isReadyForPhotoLibraryAccess else { return }
updateLayout()
}
func orientationDidChange() {
updateLayout()
}
private func updateLayout() {
AssertIsOnMainThread()
// We don't want to do anything until media library permission is granted.
guard isReadyForPhotoLibraryAccess else { return }
guard frame.height > 0 else { return }
guard itemSize.height > 0, itemSize.width > 0 else { return }
// The items should always expand to fit the height of the collection view.
// We'll always just have one row of items.
collectionViewFlowLayout.itemSize = itemSize
collectionViewFlowLayout.invalidateLayout()
reloadData()
}
required init?(coder aDecoder: NSCoder) {

View File

@ -102,6 +102,7 @@ const CGFloat kMaxTextViewHeight = 98;
@property (nonatomic) KeyboardType desiredKeyboardType;
@property (nonatomic, readonly) StickerKeyboard *stickerKeyboard;
@property (nonatomic, readonly) AttachmentKeyboard *attachmentKeyboard;
@property (nonatomic) BOOL isMeasuringKeyboardHeight;
@end
@ -1469,14 +1470,16 @@ const CGFloat kMaxTextViewHeight = 98;
// We disable animations so this preload is invisible to the
// user.
if (!self.inputTextView.isFirstResponder) {
// Flag that we're measuring the system keyboard's height, so
// even if though it won't be the first responder by the time
// the notifications fire, we'll still read its measurement
self.isMeasuringKeyboardHeight = YES;
[UIView setAnimationsEnabled:NO];
[self.inputTextView becomeFirstResponder];
// Next run loop
dispatch_async(dispatch_get_main_queue(), ^{
[self.inputTextView resignFirstResponder];
[UIView setAnimationsEnabled:YES];
});
[self.inputTextView resignFirstResponder];
[UIView setAnimationsEnabled:YES];
}
}
@ -1517,12 +1520,13 @@ const CGFloat kMaxTextViewHeight = 98;
}
CGRect keyboardEndFrame = [keyboardEndFrameValue CGRectValue];
if (self.inputTextView.isFirstResponder) {
if (self.inputTextView.isFirstResponder || self.isMeasuringKeyboardHeight) {
// The returned keyboard height includes the input view, so subtract our height.
CGFloat newHeight = keyboardEndFrame.size.height - self.frame.size.height;
if (newHeight > 0) {
[self.stickerKeyboard updateSystemKeyboardHeight:newHeight];
[self.attachmentKeyboard updateSystemKeyboardHeight:newHeight];
self.isMeasuringKeyboardHeight = NO;
}
}
}

View File

@ -1338,13 +1338,7 @@ typedef enum : NSUInteger {
- (void)updateHeaderViewFrame
{
// TODO: iOS 13 The titleView no longer respects the headerView's intrinsicContentSize
// and always tries to center the headerView. See if this changes in later betas.
BOOL iOS11and12 = NO;
if (@available(iOS 13, *)) iOS11and12 = NO;
else if (@available(iOS 11, *)) iOS11and12 = YES;
if (iOS11and12) {
if (@available(iOS 11, *)) {
// Do nothing, we use autolayout/intrinsic content size to grow
} else {
// Request "full width" title; the navigation bar will truncate this

View File

@ -50,10 +50,15 @@ open class CustomKeyboard: UIInputView {
}
open override func didMoveToSuperview() {
if superview == nil {
wasDismissed()
} else {
wasPresented()
// Call wasPresented/wasDismissed on the next run loop,
// once this view hierarchy change has finished.
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
if self.superview == nil {
self.wasDismissed()
} else {
self.wasPresented()
}
}
}
@ -81,6 +86,9 @@ open class CustomKeyboard: UIInputView {
@objc
public func updateSystemKeyboardHeight(_ height: CGFloat) {
// Only respect this height if it's reasonable, we don't want
// to have a tiny keyboard.
guard height > 100 else { return }
cachedSystemKeyboardHeight.current = height
resizeToSystemKeyboard()
}

View File

@ -301,6 +301,10 @@ public extension CGSize {
var ceil: CGSize {
return CGSizeCeil(self)
}
init(square: CGFloat) {
self.init(width: square, height: square)
}
}
// MARK: -