Merge branch 'nt/attachment-keyboard-fixes' into release/2.42.0
This commit is contained in:
commit
86ef4b032e
@ -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) {
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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()
|
||||
}
|
||||
|
||||
@ -301,6 +301,10 @@ public extension CGSize {
|
||||
var ceil: CGSize {
|
||||
return CGSizeCeil(self)
|
||||
}
|
||||
|
||||
init(square: CGFloat) {
|
||||
self.init(width: square, height: square)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
Loading…
Reference in New Issue
Block a user