Commit 037ec0ee by Orkhan Alikhanov

Moved hardcoded magic numbers, to the `Constants` struct

parent e29304ce
...@@ -83,8 +83,9 @@ open class DialogView: UIView { ...@@ -83,8 +83,9 @@ open class DialogView: UIView {
h += titleAreaSizeThatFits(width: w).height h += titleAreaSizeThatFits(width: w).height
h += buttonAreaSizeThatFits(width: w).height h += buttonAreaSizeThatFits(width: w).height
h += contentViewSizeThatFits(width: w).height h += contentViewSizeThatFits(width: w).height
h = min(h, size.height)
return CGSize(width: w, height: min(h, size.height)) return CGSize(width: w, height: h)
} }
open override func layoutSubviews() { open override func layoutSubviews() {
...@@ -103,9 +104,10 @@ open class DialogView: UIView { ...@@ -103,9 +104,10 @@ open class DialogView: UIView {
/// Override this if you are using custom view in title area /// Override this if you are using custom view in title area
open func titleAreaSizeThatFits(width: CGFloat) -> CGSize { open func titleAreaSizeThatFits(width: CGFloat) -> CGSize {
guard !titleLabel.isEmpty else { return .zero } guard !titleLabel.isEmpty else { return .zero }
var size = titleLabel.sizeThatFits(CGSize(width: width - 24 - 24, height: .greatestFiniteMagnitude)) let insets = Constants.titleArea.insets
size.width += 24 + 24 var size = titleLabel.sizeThatFits(CGSize(width: width - insets.left - insets.right, height: .greatestFiniteMagnitude))
size.height += 24 + 20 size.width += insets.left + insets.right
size.height += insets.top + insets.bottom
return size return size
} }
...@@ -113,28 +115,57 @@ open class DialogView: UIView { ...@@ -113,28 +115,57 @@ open class DialogView: UIView {
guard !nonHiddenButtons.isEmpty else { return .zero } guard !nonHiddenButtons.isEmpty else { return .zero }
let isStacked = requiredButtonAreaWidth > width let isStacked = requiredButtonAreaWidth > width
let buttonsHeight = Constants.button.height * CGFloat(isStacked ? nonHiddenButtons.count : 1)
let buttonsInterim = isStacked ? CGFloat(nonHiddenButtons.count - 1) * Constants.button.interimStacked : 0
let insets = isStacked ? Constants.buttonArea.insetsStacked : Constants.buttonArea.insets
let h = buttonsInterim + buttonsHeight + insets.bottom + insets.top
let w = min(width, isStacked ? requiredButtonAreaWidthForStacked : requiredButtonAreaWidth) let w = min(width, isStacked ? requiredButtonAreaWidthForStacked : requiredButtonAreaWidth)
let h = isStacked ? CGFloat(8 + nonHiddenButtons.count * 48) : 52
return CGSize(width: w, height: h) return CGSize(width: w, height: h)
} }
open func contentViewSizeThatFits(width: CGFloat) -> CGSize { open func contentViewSizeThatFits(width: CGFloat) -> CGSize {
guard !detailsLabel.isEmpty else { return .zero } guard !detailsLabel.isEmpty else { return .zero }
var size = detailsLabel.sizeThatFits(CGSize(width: width - 24 - 24, height: .greatestFiniteMagnitude)) let insets = titleLabel.isEmpty ? Constants.contentView.insetsNoTitle : Constants.contentView.insets
size.width += 24 + 24 var size = detailsLabel.sizeThatFits(CGSize(width: width - insets.left - insets.right, height: .greatestFiniteMagnitude))
let additional: CGFloat = titleLabel.isEmpty ? 20 : 0 // if no title area, will be pushed 20 points below size.width += insets.left + insets.right
size.height += 24 + 0 + additional size.height += insets.top + insets.bottom
return size return size
} }
} }
private struct Constants {
struct titleArea {
static let insets = UIEdgeInsets(top: 24, left: 24, bottom: 20, right: 24)
}
struct contentView {
static let insets = UIEdgeInsets(top: 0, left: 24, bottom: 24, right: 24)
static let insetsNoTitle = UIEdgeInsets(top: 20, left: 24, bottom: 24, right: 24)
}
struct buttonArea {
static let insets = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
static let insetsStacked = UIEdgeInsets(top: 6, left: 8, bottom: 14, right: 8)
}
struct button {
static let insets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8)
static let minWidth: CGFloat = 64
static let height: CGFloat = 36
static let interimStacked: CGFloat = 12
static let interim: CGFloat = 8
}
}
private extension DialogView { private extension DialogView {
func layoutTitleArea() { func layoutTitleArea() {
let size = CGSize(width: frame.width, height: titleAreaSizeThatFits(width: frame.width).height) let size = CGSize(width: frame.width, height: titleAreaSizeThatFits(width: frame.width).height)
titleArea.frame.size = size titleArea.frame.size = size
guard !titleLabel.isEmpty else { return } guard !titleLabel.isEmpty else { return }
titleLabel.frame = CGRect(x: 24, y: 24, width: size.width - 24 - 24, height: size.height - 24 - 20) let rect = CGRect(origin: .zero, size: size)
titleLabel.frame = UIEdgeInsetsInsetRect(rect, Constants.titleArea.insets)
} }
func layoutButtonArea() { func layoutButtonArea() {
...@@ -147,25 +178,29 @@ private extension DialogView { ...@@ -147,25 +178,29 @@ private extension DialogView {
let isStacked = requiredButtonAreaWidth > width let isStacked = requiredButtonAreaWidth > width
if isStacked { if isStacked {
let insets = Constants.buttonArea.insetsStacked
buttons.forEach { buttons.forEach {
let w = min($0.optimalWidth, width - 8 - 8) let w = min($0.optimalWidth, width - insets.left - insets.right)
$0.frame.size = CGSize(width: w, height: 36) $0.frame.size = CGSize(width: w, height: Constants.button.height)
$0.frame.origin.x = width - 8 - w $0.frame.origin.x = width - insets.right - w
} }
positiveButton.frame.origin.y = 6 positiveButton.frame.origin.y = insets.top
let belowPositive = positiveButton.isHidden ? 6 : positiveButton.frame.maxY + 6 + 6 let belowPositive = positiveButton.isHidden ? insets.top : positiveButton.frame.maxY + Constants.button.interimStacked
negativeButton.frame.origin.y = belowPositive negativeButton.frame.origin.y = belowPositive
neutralButton.frame.origin.y = negativeButton.isHidden ? belowPositive : (negativeButton.frame.maxY + 6 + 6) neutralButton.frame.origin.y = negativeButton.isHidden ? belowPositive : negativeButton.frame.maxY + Constants.button.interimStacked
} else { } else {
let insets = Constants.buttonArea.insets
buttons.forEach { buttons.forEach {
$0.frame.size = CGSize(width: $0.optimalWidth, height: 36) $0.frame.size = CGSize(width: $0.optimalWidth, height: Constants.button.height)
$0.frame.origin.y = 8 $0.frame.origin.y = insets.top
} }
neutralButton.frame.origin.x = 8 neutralButton.frame.origin.x = insets.left
positiveButton.frame.origin.x = width - 8 - positiveButton.frame.width positiveButton.frame.origin.x = width - insets.right - positiveButton.frame.width
negativeButton.frame.origin.x = (positiveButton.isHidden ? width : positiveButton.frame.minX) - 8 - negativeButton.frame.width
let maxX = positiveButton.isHidden ? width - insets.right : positiveButton.frame.minX - Constants.button.interim
negativeButton.frame.origin.x = maxX - negativeButton.frame.width
} }
} }
...@@ -173,8 +208,9 @@ private extension DialogView { ...@@ -173,8 +208,9 @@ private extension DialogView {
let size = CGSize(width: frame.width, height: contentViewSizeThatFits(width: frame.width).height) let size = CGSize(width: frame.width, height: contentViewSizeThatFits(width: frame.width).height)
contentView.frame.size = size contentView.frame.size = size
guard !detailsLabel.isEmpty else { return } guard !detailsLabel.isEmpty else { return }
let additional: CGFloat = titleArea.frame.height == 0 ? 20 : 0 // if no title area, push 20 points below let rect = CGRect(origin: .zero, size: size)
detailsLabel.frame = CGRect(x: 24, y: additional, width: size.width - 24 - 24, height: size.height - 24) let insets = titleArea.frame.height == 0 ? Constants.contentView.insetsNoTitle : Constants.contentView.insets
detailsLabel.frame = UIEdgeInsetsInsetRect(rect, insets)
} }
func layoutScrollView() { func layoutScrollView() {
...@@ -204,7 +240,8 @@ private extension DialogView { ...@@ -204,7 +240,8 @@ private extension DialogView {
private extension Button { private extension Button {
var optimalWidth: CGFloat { var optimalWidth: CGFloat {
return max(64, sizeThatFits(CGSize(width: .max, height: 36)).width) let size = CGSize(width: .greatestFiniteMagnitude, height: Constants.button.height)
return max(Constants.button.minWidth, sizeThatFits(size).width)
} }
} }
...@@ -223,11 +260,13 @@ private extension DialogView { ...@@ -223,11 +260,13 @@ private extension DialogView {
let buttonsWidth: CGFloat = buttons.reduce(0) { $0 + $1.optimalWidth } let buttonsWidth: CGFloat = buttons.reduce(0) { $0 + $1.optimalWidth }
let additional: CGFloat = neutralButton.isHidden ? 0 : 8 // additional spacing for neutral button let additional: CGFloat = neutralButton.isHidden ? 0 : 8 // additional spacing for neutral button
return buttonsWidth + CGFloat(buttons.count * 8) + additional let insets = Constants.buttonArea.insets
return buttonsWidth + insets.left + insets.right + CGFloat((buttons.count - 1)) * Constants.button.interim + additional
} }
var requiredButtonAreaWidthForStacked: CGFloat { var requiredButtonAreaWidthForStacked: CGFloat {
return 8 + 8 + nonHiddenButtons.reduce(0) { let insets = Constants.buttonArea.insetsStacked
return insets.left + insets.right + nonHiddenButtons.reduce(0) {
max($0, $1.optimalWidth) max($0, $1.optimalWidth)
} }
} }
...@@ -266,7 +305,7 @@ private extension DialogView { ...@@ -266,7 +305,7 @@ private extension DialogView {
[positiveButton, negativeButton, neutralButton].forEach { [positiveButton, negativeButton, neutralButton].forEach {
buttonArea.addSubview($0) buttonArea.addSubview($0)
$0.titleLabel?.font = RobotoFont.medium(with: 14) $0.titleLabel?.font = RobotoFont.medium(with: 14)
$0.contentEdgeInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8) $0.contentEdgeInsets = Constants.button.insets
} }
} }
...@@ -291,6 +330,7 @@ private extension UIScrollView { ...@@ -291,6 +330,7 @@ private extension UIScrollView {
} }
var isAtBottom: Bool { var isAtBottom: Bool {
// - 1 is to get rid of precision errors which makes divider appear even when scroll is at bottom
return contentOffset.y >= (contentSize.height - frame.height - 1) return contentOffset.y >= (contentSize.height - frame.height - 1)
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment