Fix layout in gallery detail view.
This commit is contained in:
parent
f3eea69045
commit
74ced565bd
@ -24,7 +24,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@interface MediaDetailViewController () <UIScrollViewDelegate,
|
||||
UIGestureRecognizerDelegate,
|
||||
PlayerProgressBarDelegate,
|
||||
OWSVideoPlayerDelegate>
|
||||
OWSVideoPlayerDelegate,
|
||||
LoopingVideoViewDelegate>
|
||||
|
||||
@property (nonatomic) UIScrollView *scrollView;
|
||||
@property (nonatomic) UIView *mediaView;
|
||||
@ -95,16 +96,22 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
[super viewWillAppear:animated];
|
||||
[self resetMediaFrame];
|
||||
|
||||
[self updateZoomScaleAndConstraints];
|
||||
self.scrollView.zoomScale = self.scrollView.minimumZoomScale;
|
||||
}
|
||||
|
||||
- (void)viewDidAppear:(BOOL)animated
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
[super viewDidAppear:animated];
|
||||
|
||||
if (self.isVideo && self.shouldAutoPlayVideo && !self.hasAutoPlayedVideo) {
|
||||
|
||||
[self playVideo];
|
||||
self.hasAutoPlayedVideo = YES;
|
||||
}
|
||||
@ -263,6 +270,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
LoopingVideoView *view = [[LoopingVideoView alloc] init];
|
||||
view.video = video;
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@ -282,6 +290,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
VideoPlayerView *playerView = [VideoPlayerView new];
|
||||
playerView.player = player.avPlayer;
|
||||
|
||||
return playerView;
|
||||
}
|
||||
|
||||
@ -403,26 +412,21 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
return;
|
||||
}
|
||||
|
||||
CGSize newMediaSize
|
||||
= CGSizeMake(MIN(scrollViewSize.width, mediaSize.width), MIN(scrollViewSize.height, mediaSize.height));
|
||||
OWSAssertDebug(newMediaSize.width > 0);
|
||||
OWSAssertDebug(newMediaSize.height > 0);
|
||||
|
||||
CGFloat scaleWidth = scrollViewSize.width / newMediaSize.width;
|
||||
CGFloat scaleHeight = scrollViewSize.height / newMediaSize.height;
|
||||
CGFloat minScale = MIN(scaleWidth, scaleHeight);
|
||||
CGFloat scaleWidth = scrollViewSize.width / mediaSize.width;
|
||||
CGFloat scaleHeight = scrollViewSize.height / mediaSize.height;
|
||||
CGFloat minScale = MIN(1, MIN(scaleWidth, scaleHeight));
|
||||
|
||||
// UIScrollView transforms its content.
|
||||
// Therefore its subviews operate in a different coordinate system.
|
||||
// These constraints should reflect the _transformed_ frame of the mediaView,
|
||||
// so we need to scale by the minScale.
|
||||
CGSize newMediaSizeScaled = CGSizeScale(newMediaSize, minScale);
|
||||
CGFloat yOffset = MAX(0, (scrollViewSize.height - newMediaSizeScaled.height) / 2);
|
||||
CGFloat xOffset = MAX(0, (scrollViewSize.width - newMediaSizeScaled.width) / 2);
|
||||
CGSize newMediaSize = CGSizeScale(mediaSize, minScale);
|
||||
CGFloat yOffset = MAX(0, (scrollViewSize.height - newMediaSize.height) / 2);
|
||||
CGFloat xOffset = MAX(0, (scrollViewSize.width - newMediaSize.width) / 2);
|
||||
self.mediaViewTopConstraint.constant = yOffset;
|
||||
self.mediaViewBottomConstraint.constant = yOffset;
|
||||
self.mediaViewLeadingConstraint.constant = xOffset;
|
||||
self.mediaViewTrailingConstraint.constant = -xOffset;
|
||||
self.mediaViewTrailingConstraint.constant = xOffset;
|
||||
|
||||
CGFloat maxScale = minScale * 8;
|
||||
self.scrollView.minimumZoomScale = minScale;
|
||||
@ -546,6 +550,16 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - LoopingVideoViewDelegate
|
||||
|
||||
- (void)loopingVideoViewChangedPlayerItem {
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
[self updateZoomScaleAndConstraints];
|
||||
self.scrollView.zoomScale = self.scrollView.minimumZoomScale;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@ -113,8 +113,20 @@ private class LoopingVideoPlayer: AVPlayer {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
@objc
|
||||
public protocol LoopingVideoViewDelegate: AnyObject {
|
||||
func loopingVideoViewChangedPlayerItem()
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
@objc
|
||||
public class LoopingVideoView: UIView {
|
||||
@objc
|
||||
public weak var delegate: LoopingVideoViewDelegate?
|
||||
|
||||
private let player = LoopingVideoPlayer()
|
||||
|
||||
@objc
|
||||
@ -125,16 +137,25 @@ public class LoopingVideoView: UIView {
|
||||
invalidateIntrinsicContentSize()
|
||||
|
||||
if let assetPromise = video?.assetPromise {
|
||||
assetPromise.done(on: .global(qos: .userInitiated)) { asset in
|
||||
guard asset === self.video?.asset else { return }
|
||||
|
||||
if let asset = asset {
|
||||
let playerItem = AVPlayerItem(asset: asset, automaticallyLoadedAssetKeys: ["tracks"])
|
||||
self.player.replaceCurrentItem(with: playerItem)
|
||||
self.player.play()
|
||||
|
||||
DispatchQueue.main.async { self.invalidateIntrinsicContentSize() }
|
||||
firstly {
|
||||
assetPromise
|
||||
}.map(on: .global(qos: .userInitiated)) { [weak self] asset -> Bool in
|
||||
guard let self = self,
|
||||
let asset = asset,
|
||||
asset === self.video?.asset else {
|
||||
return false
|
||||
}
|
||||
let playerItem = AVPlayerItem(asset: asset, automaticallyLoadedAssetKeys: ["tracks"])
|
||||
self.player.replaceCurrentItem(with: playerItem)
|
||||
self.player.play()
|
||||
return true
|
||||
}.done(on: .main) { [weak self] didLoadPlayer in
|
||||
guard let self = self,
|
||||
didLoadPlayer else {
|
||||
return
|
||||
}
|
||||
self.invalidateIntrinsicContentSize()
|
||||
self.delegate?.loopingVideoViewChangedPlayerItem()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user