Closed liumengdi666 closed 5 months ago
宽度在传入之前可以自己设置的 dismiss 的看看这个
public var viewDidDisappear: ViewLifeCycleHandler?
可能我描述的场景不太全面,实际上是这样的: 业务需要浏览相册时有横屏按钮,可以手动控制屏幕方向, 所以我定制了pageIndicator, 因为我们的其它页面没有做横屏的适配比较难看, 所以当browser处于横屏时点击左上角返回如果当前是横屏状态需要先切回竖屏,再点一次才返回上一级, 此时viewDidDisappear貌似不能满足我. 从新看了下PhotoBrowser的参数, 看到可以自定义autoDismiss, 于是我尝试使用了这个参数并实现了finishHandler和cancelHandler, 然而发现点击左上角触发的回调是cancelHandler并不受autoDismiss参数影响, 页面依然返回了上一级. 以下是我的部分代码:
var config = HXPhotoPicker.PhotoBrowser.Configuration()
let browser = HXPhotoPicker.PhotoBrowser(
config,
pageIndex: indexPath.item,
assets: previewAssets,
transitionalImage: cell?.photoView.image
)
browser.config.shouldAutorotate = false
browser.config.supportedInterfaceOrientations = .all
browser.autoDismiss = false
let rect = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 30)
let titleView = MyTitleView(frame: rect)
browser.previewViewController?.navigationItem.titleView = titleView
let pageIndicator = MyPhotoBrowserPageControlIndicator(frame: rect)
pageIndicator.pageChanged = { index in
titleView.titleLabel.text = "\(index+1)"
}
browser.pageIndicator = pageIndicator
browser.show(nil)
browser.finishHandler = { result, controller in
print("finishHandler")
}
browser.cancelHandler = { controller in
print("cancelHandler")
}
/// 定制titleView
open class MyTitleView: UIView {
public var titleLabel: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
titleLabel = UILabel()
titleLabel.textColor = .white
titleLabel.textAlignment = .center
addSubview(titleLabel)
}
required public init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
open override func layoutSubviews() {
super.layoutSubviews()
titleLabel.frame = bounds
}
}
/// 定制PageIndicator
open class MyPhotoBrowserPageControlIndicator: UIView, PhotoBrowserPageIndicator {
public var pageLabel: UILabel!
public var bottomButton: UIButton!
public var pageChanged: ((Int) -> Void)?
var currentPage = 0
var numberOfPages = 0
override init(frame: CGRect) {
super.init(frame: frame)
pageLabel = UILabel()
pageLabel.textColor = .white
pageLabel.textAlignment = .center
addSubview(pageLabel)
bottomButton = UIButton()
bottomButton.setTitle("test", for: .normal)
bottomButton.titleLabel?.textColor = .white
bottomButton.addTarget(self, action: #selector(onTap), for: .touchUpInside)
addSubview(bottomButton)
}
required public init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func onTap() {
if LDevice.isLandscape {
LDevice.setInterfaceOrientation(.portrait)
}else {
LDevice.setInterfaceOrientation(.landscapeRight)
}
}
public func reloadData(numberOfPages: Int, pageIndex: Int) {
self.numberOfPages = numberOfPages
self.currentPage = pageIndex
}
public func didChanged(pageIndex: Int) {
self.currentPage = pageIndex
pageLabel.text = "\(currentPage + 1)/\(numberOfPages)"
pageChanged?(pageIndex)
}
open override func layoutSubviews() {
super.layoutSubviews()
pageLabel.frame = bounds
bottomButton.frame = CGRectMake(width-100, 0, 100, height)
}
}
/// 屏幕旋转
enum LDevice {
/// 强制旋转屏幕
public static func setInterfaceOrientation(_ orientation: UIInterfaceOrientation) {
if #available(iOS 16.0, *) {
guard let scence = UIApplication.shared.connectedScenes.first as? UIWindowScene else {
return
}
var orientationMask: UIInterfaceOrientationMask = .portrait
switch orientation {
case .portrait:
orientationMask = .portrait
case .landscapeLeft:
orientationMask = .landscapeLeft
case .landscapeRight:
orientationMask = .landscapeRight
case .portraitUpsideDown:
orientationMask = .portraitUpsideDown
default:
orientationMask = .allButUpsideDown
}
let geometryPreferencesIOS = UIWindowScene.GeometryPreferences.iOS(interfaceOrientations: orientationMask)
scence.requestGeometryUpdate(geometryPreferencesIOS)
} else {
UIDevice.current.setValue(orientation.rawValue, forKey: "orientation")
UIViewController.attemptRotationToDeviceOrientation()
}
}
/// 当前scene的interface是否竖屏
public static var isPortrait: Bool {
UIApplication.shared.windows
.first?
.windowScene?
.interfaceOrientation
.isPortrait ?? true
}
/// 当前scene的interface是否横屏
public static var isLandscape: Bool {
UIApplication.shared.windows
.first?
.windowScene?
.interfaceOrientation
.isLandscape ?? true
}
}
可能我描述的场景不太全面,实际上是这样的: 业务需要浏览相册时有横屏按钮,可以手动控制屏幕方向, 所以我定制了pageIndicator, 因为我们的其它页面没有做横屏的适配比较难看, 所以当browser处于横屏时点击左上角返回如果当前是横屏状态需要先切回竖屏,再点一次才返回上一级, 此时viewDidDisappear貌似不能满足我. 从新看了下PhotoBrowser的参数, 看到可以自定义autoDismiss, 于是我尝试使用了这个参数并实现了finishHandler和cancelHandler, 然而发现点击左上角触发的回调是cancelHandler并不受autoDismiss参数影响, 页面依然返回了上一级. 以下是我的部分代码:
var config = HXPhotoPicker.PhotoBrowser.Configuration() let browser = HXPhotoPicker.PhotoBrowser( config, pageIndex: indexPath.item, assets: previewAssets, transitionalImage: cell?.photoView.image ) browser.config.shouldAutorotate = false browser.config.supportedInterfaceOrientations = .all browser.autoDismiss = false let rect = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 30) let titleView = MyTitleView(frame: rect) browser.previewViewController?.navigationItem.titleView = titleView let pageIndicator = MyPhotoBrowserPageControlIndicator(frame: rect) pageIndicator.pageChanged = { index in titleView.titleLabel.text = "\(index+1)" } browser.pageIndicator = pageIndicator browser.show(nil) browser.finishHandler = { result, controller in print("finishHandler") } browser.cancelHandler = { controller in print("cancelHandler") }
/// 定制titleView open class MyTitleView: UIView { public var titleLabel: UILabel! override init(frame: CGRect) { super.init(frame: frame) titleLabel = UILabel() titleLabel.textColor = .white titleLabel.textAlignment = .center addSubview(titleLabel) } required public init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } open override func layoutSubviews() { super.layoutSubviews() titleLabel.frame = bounds } } /// 定制PageIndicator open class MyPhotoBrowserPageControlIndicator: UIView, PhotoBrowserPageIndicator { public var pageLabel: UILabel! public var bottomButton: UIButton! public var pageChanged: ((Int) -> Void)? var currentPage = 0 var numberOfPages = 0 override init(frame: CGRect) { super.init(frame: frame) pageLabel = UILabel() pageLabel.textColor = .white pageLabel.textAlignment = .center addSubview(pageLabel) bottomButton = UIButton() bottomButton.setTitle("test", for: .normal) bottomButton.titleLabel?.textColor = .white bottomButton.addTarget(self, action: #selector(onTap), for: .touchUpInside) addSubview(bottomButton) } required public init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } @objc func onTap() { if LDevice.isLandscape { LDevice.setInterfaceOrientation(.portrait) }else { LDevice.setInterfaceOrientation(.landscapeRight) } } public func reloadData(numberOfPages: Int, pageIndex: Int) { self.numberOfPages = numberOfPages self.currentPage = pageIndex } public func didChanged(pageIndex: Int) { self.currentPage = pageIndex pageLabel.text = "\(currentPage + 1)/\(numberOfPages)" pageChanged?(pageIndex) } open override func layoutSubviews() { super.layoutSubviews() pageLabel.frame = bounds bottomButton.frame = CGRectMake(width-100, 0, 100, height) } } /// 屏幕旋转 enum LDevice { /// 强制旋转屏幕 public static func setInterfaceOrientation(_ orientation: UIInterfaceOrientation) { if #available(iOS 16.0, *) { guard let scence = UIApplication.shared.connectedScenes.first as? UIWindowScene else { return } var orientationMask: UIInterfaceOrientationMask = .portrait switch orientation { case .portrait: orientationMask = .portrait case .landscapeLeft: orientationMask = .landscapeLeft case .landscapeRight: orientationMask = .landscapeRight case .portraitUpsideDown: orientationMask = .portraitUpsideDown default: orientationMask = .allButUpsideDown } let geometryPreferencesIOS = UIWindowScene.GeometryPreferences.iOS(interfaceOrientations: orientationMask) scence.requestGeometryUpdate(geometryPreferencesIOS) } else { UIDevice.current.setValue(orientation.rawValue, forKey: "orientation") UIViewController.attemptRotationToDeviceOrientation() } } /// 当前scene的interface是否竖屏 public static var isPortrait: Bool { UIApplication.shared.windows .first? .windowScene? .interfaceOrientation .isPortrait ?? true } /// 当前scene的interface是否横屏 public static var isLandscape: Bool { UIApplication.shared.windows .first? .windowScene? .interfaceOrientation .isLandscape ?? true } }
需要界面退出之后的回调吗?
需要界面退出之后的回调现在是有的,实际上我们只想自定义左上角返回按钮事件,我用了个比较非常规的方法:
browser.show(nil)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in
guard let self = self else { return }
var item = browser.previewViewController?.navigationItem.leftBarButtonItem
item?.action = #selector(didCancelItemClick1)
item?.target = self
}
这样也替换了左上角事件, 我自己来控制dismiss, 结合自定义cell单击事件,也勉强达到了想要的效果.
Hello, 作者你好, 上次提的几个问题很快修复,非常感谢. 本次用到HXPhotoPicker.PhotoBrowser(4.1.8)的几个功能,遇到几个问题,麻烦看下:
自定义pageIndicator不生效 看起来虽然外部支持传入自定义pageIndicator,但是内部viewDidLoad已经执行并加载了默认的pageIndicator
当pageIndicatorType = .titleView时不显示 看起来是viewDidLayoutSubviews时没有设置宽度导致宽度为0
3.我这有个需求, 期望可以自定义左上角dismiss事件用以埋点或其它业务需求