更新实例后自动更新window布局

This commit is contained in:
xaoxuu 2023-08-22 15:44:07 +08:00
parent c3afd50eac
commit c57b859555
6 changed files with 114 additions and 68 deletions

View File

@ -189,8 +189,8 @@ class DemoCapsuleVC: ListVC {
section.add(title: "指定id=a, haha") { section.add(title: "指定id=a, haha") {
Capsule(.identifier("a").message("id=a, haha")) Capsule(.identifier("a").message("id=a, haha"))
} }
section.add(title: "指定id=a, hahaha") { section.add(title: "指定id=a, hahahahahaha") {
Capsule(.identifier("a").message("id=a, hahaha")) Capsule(.identifier("a").message("id=a, hahahahahaha"))
} }
} }

View File

@ -233,7 +233,7 @@ class DemoToastVC: ListVC {
} }
section.add(title: "不存在就创建,存在就更新") { section.add(title: "不存在就创建,存在就更新") {
i += 1 i += 1
Toast(.identifier("loading").title("正在加载\(i)").message("这条消息不会重复显示多条")) Toast(.identifier("loading").title("正在加载\(i)").message("这条消息\n不会重复显示多条"))
} }
section.add(title: "如果存在就更新,如果不存在就忽略") { section.add(title: "如果存在就更新,如果不存在就忽略") {
i += 1 i += 1

View File

@ -25,7 +25,9 @@ extension CapsuleTarget: DefaultLayout {
loadContentMaskViewIfNeeded() loadContentMaskViewIfNeeded()
// text // 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: " ") var text = [vm?.title ?? "", vm?.message ?? ""].filter({ $0.count > 0 }).joined(separator: " ")
if text.count > 0 { if text.count > 0 {
textLabel.snp.remakeConstraints { make in textLabel.snp.remakeConstraints { make in
@ -47,6 +49,7 @@ extension CapsuleTarget: DefaultLayout {
UIView.animateEaseOut(duration: config.animateDurationForReloadByDefault) { UIView.animateEaseOut(duration: config.animateDurationForReloadByDefault) {
self.view.layoutIfNeeded() self.view.layoutIfNeeded()
} }
updateWindowSize()
} }
} }
@ -88,7 +91,9 @@ extension CapsuleTarget: DefaultLayout {
if vm?.icon == nil && vm?.iconURL == nil { if vm?.icon == nil && vm?.iconURL == nil {
contentStack.removeArrangedSubview(imageView) contentStack.removeArrangedSubview(imageView)
} else { } else {
contentStack.insertArrangedSubview(imageView, at: 0) if contentStack.arrangedSubviews.contains(imageView) == false {
contentStack.insertArrangedSubview(imageView, at: 0)
}
if config.iconSizeByDefault != .zero { if config.iconSizeByDefault != .zero {
imageView.snp.remakeConstraints { make in imageView.snp.remakeConstraints { make in
make.height.equalTo(config.iconSizeByDefault) 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()
}
}
} }

View File

@ -43,30 +43,11 @@ extension CapsuleTarget {
window = CapsuleWindow(capsule: self) window = CapsuleWindow(capsule: self)
windows[position] = nil windows[position] = nil
} }
window.isUserInteractionEnabled = tapActionCallback != 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 window.transform = .identity
if isNew { if isNew {
window.frame = newFrame window.frame = newFrame

View File

@ -87,13 +87,14 @@ extension ToastTarget: DefaultLayout {
bodyLabel.text = vm?.message bodyLabel.text = vm?.message
view.layoutIfNeeded() view.layoutIfNeeded()
setupImageView()
if isViewAppeared { if isViewAppeared {
// //
updateTimeoutDuration() updateTimeoutDuration()
updateWindowSize()
} }
setupImageView()
} }
func loadContentViewIfNeeded() { 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
}
} }

View File

@ -9,32 +9,6 @@ import UIKit
extension ToastTarget { 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() { @objc open func push() {
guard ToastConfiguration.isEnabled else { return } guard ToastConfiguration.isEnabled else { return }
let isNew: Bool let isNew: Bool
@ -49,23 +23,14 @@ extension ToastTarget {
isNew = true 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.sizewindow.frame.size
if windows.contains(window) == false { if windows.contains(window) == false {
windows.append(window) windows.append(window)
setContextWindows(windows) 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.sizewindow.frame.size
ToastWindow.updateToastWindowsLayout(windows: windows) ToastWindow.updateToastWindowsLayout(windows: windows)
// //
updateTimeoutDuration() updateTimeoutDuration()