接上文 Flutter PIP 插件 ---- 新增PipActivity,Android 11以下支持自動進入PIP Mode
項目地址 PIP, pub.dev也已經同步發布 pip 0.0.3,你的加星和點贊,將是我繼續改進最大的動力
在之前的界面設計中,還原動畫等體驗一直不太好,遂優化一下,現在體驗效果看起來更好了,
唯一一個還沒搞定的是應用內還原的動畫,應用內還原的時候,有一個從小到達逐漸拉伸的效果,猜測可能是和圖片的渲染有關?有大佬能指點一二不?
不再獲取PipViewController
前面也講到這個比較危險,雖然多方求證似乎也沒什么,但還是怕,所以改成查找PipWindow,并在pictureInPictureControllerDidStartPictureInPicture通知中把自渲染View添加到rootView中去
- (void)pictureInPictureControllerDidStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {PIP_LOG(@"pictureInPictureControllerDidStartPictureInPicture");#if USE_PIP_VIEW_CONTROLLER// if you use the pipViewController, you must call this every time to bring// the content view to the front, otherwise the content view will not be// visible and covered by the pip host view.if (_pipViewController) {[_pipViewController.view bringSubviewToFront:_contentView];}
#else// TODO @sylar: check if this is the best way to do this, what will happen if// we have multiple windows? what if the root view controller is not a// UIViewController?UIWindow *window = [[UIApplication sharedApplication] windows].firstObject;if (window) {UIViewController *rootViewController = window.rootViewController;UIView *superview = rootViewController.view.superview;[self insertContentViewIfNeeded:superview];} else {PIP_LOG(@"pictureInPictureControllerDidStartPictureInPicture: window is nil");[_pipStateDelegate pipStateChanged:PipStateFailederror:@"Can not find the pip window"];return;}
#endif_isPipActived = YES;[_pipStateDelegate pipStateChanged:PipStateStarted error:nil];
}
遺留項是,這個查找PipWindow的方法靠不靠譜?有其他方法但是看起來也不靠譜
不再每次都將自渲染UIView從PipWindow移除
觀察到一個現象是,如果是依賴PipViewController在 pictureInPictureControllerWillStartPictureInPicture 中添加UIView,還必須得在 pictureInPictureControllerDidStartPictureInPicture 中調用一次 bringSubviewToFront,否則的話你會比系統自動添加的View早添加,導致你的層級在下面;改用通過獲取PipWindow方式后,就不用在bringSubviewToFront,因為不是一個parent了。
另外一些場景下可能會創建一個懸空的UIView用來做渲染,這樣的話我們就沒必要每次都把他從PipWindow上移除還原到父parent上,可以在PipWindow顯示的一瞬間就立即看到渲染的內容
- (void)pictureInPictureControllerDidStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {PIP_LOG(@"pictureInPictureControllerDidStopPictureInPicture");// restore the content view in// pictureInPictureControllerDidStopPictureInPicture will have the best user// experience.[self restoreContentViewIfNeeded];_isPipActived = NO;[_pipStateDelegate pipStateChanged:PipStateStopped error:nil];
}- (void)restoreContentViewIfNeeded {if (_contentView == nil) {PIP_LOG(@"restoreContentViewIfNeeded: contentView is nil");return;}// do not restore the content view if the original parent view is nil or// the content view is already in the original parent view.// keep the content view in the pip view controller will make the user// experience better, the pip content view will be visible immediately.if (_contentViewOriginalParentView == nil ||[_contentViewOriginalParentView.subviews containsObject:_contentView]) {PIP_LOG(@"restoreContentViewIfNeeded: _contentViewOriginalParentView is nil or "@"contentView is already in the original parent view");return;}[_contentView removeFromSuperview];PIP_LOG(@"restoreContentViewIfNeeded: contentView is removed from the original "@"parent view");if (_contentViewOriginalParentView != nil) {// in case that the subviews of _contentViewOriginalParentView has been// changed, we need to get the real index of the content view.NSUInteger trueIndex = MIN(_contentViewOriginalParentView.subviews.count,_contentViewOriginalIndex);[_contentViewOriginalParentView insertSubview:_contentViewatIndex:trueIndex];PIP_LOG(@"restoreContentViewIfNeeded: contentView is added to the original "@"parent view "@"at index: %lu",trueIndex);// restore the original frame_contentView.frame = _contentViewOriginalFrame;// restore the original constraints[_contentView removeConstraints:_contentView.constraints.copy];[_contentView addConstraints:_contentViewOriginalConstraints];// restore the original translatesAutoresizingMaskIntoConstraints_contentView.translatesAutoresizingMaskIntoConstraints =_contentViewOriginalTranslatesAutoresizingMaskIntoConstraints;// restore the original parent view[_contentViewOriginalParentViewremoveConstraints:_contentViewOriginalParentView.constraints.copy];[_contentViewOriginalParentViewaddConstraints:_contentViewOriginalParentViewConstraints];}
}
支持動態設置PipWindow窗口大小
這個沒什么好說的,修改創建contentSource的時候的sampleBufferDisplayer的大小就可以動態修改PipWindow窗口大小,判斷各種對象都已經有了的話就只修改大小而不用重新創建controller就行了
if (options.preferredContentSize.width > 0 &&options.preferredContentSize.height > 0) {[_pipViewupdateFrameSize:CGSizeMake(options.preferredContentSize.width,options.preferredContentSize.height)];
}
重要的事情說三遍
項目地址 PIP, pub.dev也已經同步發布 pip 0.0.3,你的加星和點贊,將是我繼續改進最大的動力
項目地址 PIP, pub.dev也已經同步發布 pip 0.0.3,你的加星和點贊,將是我繼續改進最大的動力
項目地址 PIP, pub.dev也已經同步發布 pip 0.0.3,你的加星和點贊,將是我繼續改進最大的動力