|
//
// FFAlertView.swift
// FFAlert
//
// Created by FFIB on 2017/11/14.
// Copyright © 2017年 FFIB. All rights reserved.
//
import UIKit
class FFAlertView: UIView, FFAlertRepresentable {
var titleLabel = FFAlertLabel()
var messageLabel = FFAlertLabel()
var contentView: UIView?
var title: NSAttributedString?
var message: NSAttributedString?
let buttonTag = 7070657369
var contentEdgInsets = UIEdgeInsets(top: 10, left: 6, bottom: 15, right: 6)
var contentHeight: CGFloat = 0
var edgInsets: (left: CGFloat, right: CGFloat) = (40, 40)
private let labelLeading: CGFloat = 12
private let labelTrailing: CGFloat = 12
private var titleTop: CGFloat = 10
private var messageTop: CGFloat = 14
var alertActions = [FFAlertAction]()
var isNeedlayout = true
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func layoutSubviews() {
super.layoutSubviews()
if isNeedlayout {
configurationOfTitle()
configurationOfMessage()
configurationOfContentView()
configurationOfAlertAction()
isNeedlayout = false
}
}
private func configurationOfContentView() {
if contentView == nil {
contentView = UIView()
}
addSubview(contentView!)
contentView!.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate(
[NSLayoutConstraint(item: contentView!, attribute: .leading,
relatedBy: .equal,
toItem: self, attribute: .leading,
multiplier: 1, constant: contentEdgInsets.left),
NSLayoutConstraint(item: contentView!, attribute: .trailing,
relatedBy: .equal,
toItem: self, attribute: .trailing,
multiplier: 1, constant: -contentEdgInsets.right),
NSLayoutConstraint(item: contentView!, attribute: .top,
relatedBy: .equal,
toItem: messageLabel, attribute: .bottom,
multiplier: 1, constant: contentEdgInsets.top),
NSLayoutConstraint(item: contentView!, attribute: .height,
relatedBy: .equal,
toItem: nil, attribute: .height,
multiplier: 1, constant: contentHeight)
]
)
if alertActions.count == 0 {
NSLayoutConstraint.activate(
[NSLayoutConstraint(item: contentView!, attribute: .bottom,
relatedBy: .equal,
toItem: self, attribute: .bottom,
multiplier: 1, constant: -contentEdgInsets.bottom)]
)
}
contentView!.setContentCompressionResistancePriority(.required, for: .vertical)
}
private func configurationOfTitle() {
titleTop = title!.string.isEmpty ? 0 : titleTop
addSubview(titleLabel)
titleLabel.attributedText = title
NSLayoutConstraint.activate(
[NSLayoutConstraint(item: titleLabel, attribute: .leading,
relatedBy: .equal,
toItem: self, attribute: .leading,
multiplier: 1, constant: labelLeading),
NSLayoutConstraint(item: titleLabel, attribute: .trailing,
relatedBy: .equal,
toItem: self, attribute: .trailing,
multiplier: 1, constant: -labelTrailing),
NSLayoutConstraint(item: titleLabel, attribute: .top,
relatedBy: .equal,
toItem: self, attribute: .top,
multiplier: 1, constant: titleTop)]
)
}
private func configurationOfMessage() {
messageTop = message!.string.isEmpty ? 0 : messageTop
addSubview(messageLabel)
messageLabel.attributedText = message
NSLayoutConstraint.activate(
[NSLayoutConstraint(item: messageLabel, attribute: .leading,
relatedBy: .equal,
toItem: self, attribute: .leading,
multiplier: 1, constant: labelLeading),
NSLayoutConstraint(item: messageLabel, attribute: .trailing,
relatedBy: .equal,
toItem: self, attribute: .trailing,
multiplier: 1, constant: -labelTrailing),
NSLayoutConstraint(item: messageLabel, attribute: .top,
relatedBy: .equal,
toItem: titleLabel, attribute: .bottom,
multiplier: 1, constant: messageTop)]
)
}
private func configurationOfAlertAction() {
var last: UIButton?
let buttonWidth = (UIScreen.main.bounds.width - edgInsets.left - edgInsets.right - contentEdgInsets.left - contentEdgInsets.right) / CGFloat(alertActions.count)
for (i, alertAction) in alertActions.enumerated() {
let button = UIButton(type: .custom)
button.translatesAutoresizingMaskIntoConstraints = false
button.setAttributedTitle(alertAction.attributedTitle, for: .normal)
button.addTarget(self, action: #selector(click(button:)), for: .touchDown)
addSubview(button)
button.backgroundColor = alertAction.backgroundColor
button.tag = buttonTag + i
let actionEdgInsets = alertAction.contentEdgInsets != nil ? alertAction.contentEdgInsets! : UIEdgeInsets(top: 6, left: 16, bottom: 15, right: 0)
NSLayoutConstraint.activate(
[NSLayoutConstraint(item: button, attribute: .leading,
relatedBy: .equal,
toItem: last ?? self, attribute: last == nil ? .leading : .trailing,
multiplier: 1, constant: actionEdgInsets.left),
NSLayoutConstraint(item: button, attribute: .width,
relatedBy: .equal,
toItem: nil, attribute: .width,
multiplier: 1, constant:buttonWidth - actionEdgInsets.left - actionEdgInsets.right),
NSLayoutConstraint(item: button, attribute: .top,
relatedBy: .equal,
toItem: contentView, attribute: .bottom,
multiplier: 1, constant: actionEdgInsets.top),
NSLayoutConstraint(item: button, attribute: .bottom,
relatedBy: .equal,
toItem: self, attribute: .bottom,
multiplier: 1, constant: -actionEdgInsets.bottom)]
)
last = button
}
}
@objc
private func click(button: UIButton) {
var r = next
while r != nil {
if let ctl = r as? UIViewController, ctl.isKind(of: FFAlertController.classForCoder()) {
ctl.dismiss(animated: true, completion: nil)
}
r = r?.next
}
let alertAction = alertActions[button.tag - buttonTag]
if let handler = alertAction.handler {
handler(alertAction)
}
}
}
|