mirror of https://github.com/xaoxuu/ProHUD
更新实例后自动更新window布局
This commit is contained in:
parent
c3afd50eac
commit
c57b859555
|
@ -189,8 +189,8 @@ class DemoCapsuleVC: ListVC {
|
|||
section.add(title: "指定id=a, haha") {
|
||||
Capsule(.identifier("a").message("id=a, haha"))
|
||||
}
|
||||
section.add(title: "指定id=a, hahaha") {
|
||||
Capsule(.identifier("a").message("id=a, hahaha"))
|
||||
section.add(title: "指定id=a, hahahahahaha") {
|
||||
Capsule(.identifier("a").message("id=a, hahahahahaha"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -233,7 +233,7 @@ class DemoToastVC: ListVC {
|
|||
}
|
||||
section.add(title: "不存在就创建,存在就更新") {
|
||||
i += 1
|
||||
Toast(.identifier("loading").title("正在加载\(i)").message("这条消息不会重复显示多条"))
|
||||
Toast(.identifier("loading").title("正在加载\(i)").message("这条消息\n不会重复显示多条"))
|
||||
}
|
||||
section.add(title: "如果存在就更新,如果不存在就忽略") {
|
||||
i += 1
|
||||
|
|
|
@ -25,7 +25,9 @@ extension CapsuleTarget: DefaultLayout {
|
|||
loadContentMaskViewIfNeeded()
|
||||
|
||||
// text
|
||||
contentStack.addArrangedSubview(textLabel)
|
||||
if contentStack.arrangedSubviews.contains(textLabel) == false {
|
||||
contentStack.addArrangedSubview(textLabel)
|
||||
}
|
||||
var text = [vm?.title ?? "", vm?.message ?? ""].filter({ $0.count > 0 }).joined(separator: " ")
|
||||
if text.count > 0 {
|
||||
textLabel.snp.remakeConstraints { make in
|
||||
|
@ -47,6 +49,7 @@ extension CapsuleTarget: DefaultLayout {
|
|||
UIView.animateEaseOut(duration: config.animateDurationForReloadByDefault) {
|
||||
self.view.layoutIfNeeded()
|
||||
}
|
||||
updateWindowSize()
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -88,7 +91,9 @@ extension CapsuleTarget: DefaultLayout {
|
|||
if vm?.icon == nil && vm?.iconURL == nil {
|
||||
contentStack.removeArrangedSubview(imageView)
|
||||
} else {
|
||||
contentStack.insertArrangedSubview(imageView, at: 0)
|
||||
if contentStack.arrangedSubviews.contains(imageView) == false {
|
||||
contentStack.insertArrangedSubview(imageView, at: 0)
|
||||
}
|
||||
if config.iconSizeByDefault != .zero {
|
||||
imageView.snp.remakeConstraints { make in
|
||||
make.height.equalTo(config.iconSizeByDefault)
|
||||
|
@ -106,4 +111,47 @@ extension CapsuleTarget: DefaultLayout {
|
|||
|
||||
}
|
||||
|
||||
func getWindowSize(window: CapsuleWindow) -> CGSize {
|
||||
let cardEdgeInsetsByDefault = config.cardEdgeInsetsByDefault
|
||||
view.layoutIfNeeded()
|
||||
var size = contentStack.frame.size
|
||||
let width = min(config.cardMaxWidthByDefault, size.width + cardEdgeInsetsByDefault.left + cardEdgeInsetsByDefault.right)
|
||||
let height = min(config.cardMaxHeightByDefault, size.height + cardEdgeInsetsByDefault.top + cardEdgeInsetsByDefault.bottom)
|
||||
return .init(width: width, height: max(height, config.cardMinHeight))
|
||||
}
|
||||
|
||||
func getWindowFrame(size: CGSize) -> CGRect {
|
||||
// 应用到frame
|
||||
let newFrame: CGRect
|
||||
switch vm?.position {
|
||||
case .top, .none:
|
||||
let topLayoutMargins = AppContext.appWindow?.safeAreaInsets.top ?? 8
|
||||
let y = max(topLayoutMargins, 8)
|
||||
newFrame = .init(x: (AppContext.appBounds.width - size.width) / 2, y: y, width: size.width, height: size.height)
|
||||
case .middle:
|
||||
newFrame = .init(x: (AppContext.appBounds.width - size.width) / 2, y: (AppContext.appBounds.height - size.height) / 2 - 20, width: size.width, height: size.height)
|
||||
case .bottom:
|
||||
let bottomLayoutMargins = AppContext.appWindow?.layoutMargins.bottom ?? 8
|
||||
let y = AppContext.appBounds.height - bottomLayoutMargins - size.height - 60
|
||||
newFrame = .init(x: (AppContext.appBounds.width - size.width) / 2, y: y, width: size.width, height: size.height)
|
||||
}
|
||||
return newFrame
|
||||
}
|
||||
|
||||
func updateWindowSize() {
|
||||
guard let window = view.window as? CapsuleWindow else { return }
|
||||
window.isUserInteractionEnabled = tapActionCallback != nil
|
||||
let size = getWindowSize(window: window)
|
||||
let newFrame = getWindowFrame(size: size)
|
||||
window.transform = .identity
|
||||
view.layoutIfNeeded()
|
||||
UIView.animate(withDuration: 0.2, delay: 0, options: .curveEaseOut) {
|
||||
window.frame = newFrame
|
||||
window.layoutIfNeeded()
|
||||
}
|
||||
if vm?.position == .top {
|
||||
ToastWindow.updateToastWindowsLayout()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -43,30 +43,11 @@ extension CapsuleTarget {
|
|||
window = CapsuleWindow(capsule: self)
|
||||
windows[position] = nil
|
||||
}
|
||||
|
||||
window.isUserInteractionEnabled = tapActionCallback != nil
|
||||
// frame
|
||||
let cardEdgeInsetsByDefault = config.cardEdgeInsetsByDefault
|
||||
view.layoutIfNeeded()
|
||||
var size = contentStack.frame.size
|
||||
let width = min(config.cardMaxWidthByDefault, size.width + cardEdgeInsetsByDefault.left + cardEdgeInsetsByDefault.right)
|
||||
let height = min(config.cardMaxHeightByDefault, size.height + cardEdgeInsetsByDefault.top + cardEdgeInsetsByDefault.bottom)
|
||||
size = CGSize(width: width, height: max(height, config.cardMinHeight))
|
||||
|
||||
// 应用到frame
|
||||
let newFrame: CGRect
|
||||
switch vm?.position {
|
||||
case .top, .none:
|
||||
let topLayoutMargins = AppContext.appWindow?.safeAreaInsets.top ?? 8
|
||||
let y = max(topLayoutMargins, 8)
|
||||
newFrame = .init(x: (AppContext.appBounds.width - size.width) / 2, y: y, width: size.width, height: size.height)
|
||||
case .middle:
|
||||
newFrame = .init(x: (AppContext.appBounds.width - size.width) / 2, y: (AppContext.appBounds.height - size.height) / 2 - 20, width: size.width, height: size.height)
|
||||
case .bottom:
|
||||
let bottomLayoutMargins = AppContext.appWindow?.layoutMargins.bottom ?? 8
|
||||
let y = AppContext.appBounds.height - bottomLayoutMargins - size.height - 60
|
||||
newFrame = .init(x: (AppContext.appBounds.width - size.width) / 2, y: y, width: size.width, height: size.height)
|
||||
}
|
||||
|
||||
let size = getWindowSize(window: window)
|
||||
let newFrame = getWindowFrame(size: size)
|
||||
window.transform = .identity
|
||||
if isNew {
|
||||
window.frame = newFrame
|
||||
|
|
|
@ -87,13 +87,14 @@ extension ToastTarget: DefaultLayout {
|
|||
bodyLabel.text = vm?.message
|
||||
view.layoutIfNeeded()
|
||||
|
||||
setupImageView()
|
||||
|
||||
if isViewAppeared {
|
||||
// 更新时间
|
||||
updateTimeoutDuration()
|
||||
updateWindowSize()
|
||||
}
|
||||
|
||||
setupImageView()
|
||||
|
||||
}
|
||||
|
||||
func loadContentViewIfNeeded() {
|
||||
|
@ -155,4 +156,55 @@ extension ToastTarget {
|
|||
|
||||
}
|
||||
|
||||
func getWindowSize(window: ToastWindow) -> CGSize {
|
||||
let cardEdgeInsets = config.cardEdgeInsetsByDefault
|
||||
let width = CGFloat.minimum(AppContext.appBounds.width - config.marginX - config.marginX, config.cardMaxWidthByDefault)
|
||||
view.frame.size = CGSize(width: width, height: config.cardMaxHeightByDefault) // 以最大高度开始布局,然后计算实际需要高度
|
||||
titleLabel.sizeToFit()
|
||||
bodyLabel.sizeToFit()
|
||||
view.layoutIfNeeded()
|
||||
// 更新子视图之后获取正确的高度
|
||||
let height = calcHeight()
|
||||
let size = CGSize(width: width, height: height)
|
||||
view.frame.size = size
|
||||
view.layoutIfNeeded()
|
||||
return size
|
||||
}
|
||||
|
||||
func updateWindowSize() {
|
||||
guard let window = view.window as? ToastWindow else { return }
|
||||
let lastSize = view.frame.size
|
||||
let newSize = getWindowSize(window: window)
|
||||
view.frame.size = lastSize
|
||||
view.layoutIfNeeded()
|
||||
window.frame.size = newSize
|
||||
ToastWindow.updateToastWindowsLayout()
|
||||
}
|
||||
|
||||
private func calcHeight() -> CGFloat {
|
||||
var height = CGFloat(0)
|
||||
for v in infoStack.arrangedSubviews {
|
||||
// 图片或者文本最大高度
|
||||
height = CGFloat.maximum(v.frame.maxY, height)
|
||||
}
|
||||
if actionStack.arrangedSubviews.count > 0 {
|
||||
height += actionStack.frame.height + contentStack.spacing
|
||||
}
|
||||
contentView.subviews.filter { v in
|
||||
if v == contentMaskView {
|
||||
return false
|
||||
}
|
||||
if v == contentStack {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} .forEach { v in
|
||||
height = CGFloat.maximum(v.frame.maxY, height)
|
||||
}
|
||||
// 上下边间距
|
||||
let cardEdgeInsets = config.cardEdgeInsetsByDefault
|
||||
height += cardEdgeInsets.top + cardEdgeInsets.bottom
|
||||
return height
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,32 +9,6 @@ import UIKit
|
|||
|
||||
extension ToastTarget {
|
||||
|
||||
private func calcHeight() -> CGFloat {
|
||||
var height = CGFloat(0)
|
||||
for v in infoStack.arrangedSubviews {
|
||||
// 图片或者文本最大高度
|
||||
height = CGFloat.maximum(v.frame.maxY, height)
|
||||
}
|
||||
if actionStack.arrangedSubviews.count > 0 {
|
||||
height += actionStack.frame.height + contentStack.spacing
|
||||
}
|
||||
contentView.subviews.filter { v in
|
||||
if v == contentMaskView {
|
||||
return false
|
||||
}
|
||||
if v == contentStack {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} .forEach { v in
|
||||
height = CGFloat.maximum(v.frame.maxY, height)
|
||||
}
|
||||
// 上下边间距
|
||||
let cardEdgeInsets = config.cardEdgeInsetsByDefault
|
||||
height += cardEdgeInsets.top + cardEdgeInsets.bottom
|
||||
return height
|
||||
}
|
||||
|
||||
@objc open func push() {
|
||||
guard ToastConfiguration.isEnabled else { return }
|
||||
let isNew: Bool
|
||||
|
@ -49,23 +23,14 @@ extension ToastTarget {
|
|||
isNew = true
|
||||
}
|
||||
|
||||
// frame
|
||||
let cardEdgeInsets = config.cardEdgeInsetsByDefault
|
||||
let width = CGFloat.minimum(AppContext.appBounds.width - config.marginX - config.marginX, config.cardMaxWidthByDefault)
|
||||
view.frame.size = CGSize(width: width, height: config.cardMaxHeightByDefault)
|
||||
titleLabel.sizeToFit()
|
||||
bodyLabel.sizeToFit()
|
||||
view.layoutIfNeeded()
|
||||
// 更新子视图之后获取正确的高度
|
||||
let height = calcHeight()
|
||||
view.frame.size = CGSize(width: width, height: height)
|
||||
// 应用到frame
|
||||
window.frame = CGRect(x: (AppContext.appBounds.width - width) / 2, y: 0, width: width, height: height)
|
||||
window.rootViewController = self // 此时toast.view.frame.size会自动更新为window.frame.size
|
||||
if windows.contains(window) == false {
|
||||
windows.append(window)
|
||||
setContextWindows(windows)
|
||||
}
|
||||
let size = getWindowSize(window: window)
|
||||
window.frame = CGRect(x: (AppContext.appBounds.width - size.width) / 2, y: 0, width: size.width, height: size.height)
|
||||
window.rootViewController = self // 此时toast.view.frame.size会自动更新为window.frame.size
|
||||
|
||||
ToastWindow.updateToastWindowsLayout(windows: windows)
|
||||
// 为了更连贯,从进入动画开始时就开始计时
|
||||
updateTimeoutDuration()
|
||||
|
|
Loading…
Reference in New Issue