| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- //
- // SAIInputItemView.swift
- // SAIInputBar
- //
- // Created by SAGESSE on 8/3/16.
- // Copyright © 2016-2017 SAGESSE. All rights reserved.
- //
- import UIKit
- internal class SAIInputItemView: UICollectionViewCell {
-
- var item: SAIInputItem? {
- willSet {
- UIView.performWithoutAnimation {
- self._updateItem(newValue)
- }
- }
- }
-
- weak var delegate: SAIInputItemViewDelegate? {
- set { return _button.delegate = newValue }
- get { return _button.delegate }
- }
-
- func setSelected(_ selected: Bool, animated: Bool) {
- _button.setSelected(selected: selected, animated: animated)
- }
-
- func _init() {
-
- clipsToBounds = true
- backgroundColor = .clear
- //backgroundColor = UIColor.greenColor().colorWithAlphaComponent(0.2)
- }
- func _updateItem(_ newValue: SAIInputItem?) {
-
- guard let newValue = newValue else {
- // clear on nil
- _contentView?.removeFromSuperview()
- _contentView = nil
- return
- }
-
- if let customView = newValue.customView {
- // 需要显示自定义视图
- _contentView?.removeFromSuperview()
- _contentView = customView
- } else {
- // 显示普通按钮
- if _contentView !== _button {
- _contentView?.removeFromSuperview()
- _contentView = _button
- }
- // 更新按钮属性
- _button.barItem = newValue
- }
- // 更新视图
- if let view = _contentView, view.superview != contentView {
- view.frame = contentView.bounds
- view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
- contentView.addSubview(view)
- }
- }
-
- private var _contentView: UIView?
- private lazy var _button: SAIInputItemButton = {
- let view = SAIInputItemButton(type: .custom)
- //let view = SAIInputItemButton(type: .System)
- view.isMultipleTouchEnabled = false
- view.isExclusiveTouch = true
- return view
- }()
-
- override init(frame: CGRect) {
- super.init(frame: frame)
- _init()
- }
- required init?(coder aDecoder: NSCoder) {
- super.init(coder: aDecoder)
- _init()
- }
- }
- internal class SAIInputItemButton: UIButton {
-
- override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
- guard let barItem = self.barItem else {
- return super.beginTracking(touch, with: event)
- }
- if delegate?.barItem(shouldHighlightFor: barItem) ?? true {
- allowsHighlight = true
- delegate?.barItem(didHighlightFor: barItem)
- } else {
- allowsHighlight = false
- }
- return super.beginTracking(touch, with: event)
- }
-
- var barItem: SAIInputItem? {
- willSet {
- guard barItem !== newValue else {
- return
- }
- UIView.performWithoutAnimation {
- guard let item = newValue else {
- return
- }
- self._updateBarItem(item)
- }
- }
- }
- weak var delegate: SAIInputItemViewDelegate?
-
- var allowsHighlight = true
- var _selected: Bool = false
-
- override var isHighlighted: Bool {
- set {
- guard allowsHighlight else {
- return
- }
- super.isHighlighted = newValue
- _setHighlighted(newValue, animated: true)
- }
- get { return super.isHighlighted }
- }
- override var state: UIControl.State {
- // 永远禁止系统的选中
- return super.state.subtracting(.selected)
- }
-
- func setSelected(selected: Bool, animated: Bool) {
- //logger.trace(selected)
-
- let op1: UIControl.State = [(selected ? .selected : .normal), .normal]
- let op2: UIControl.State = [(selected ? .selected : .normal), .highlighted]
-
- let n = barItem?.image(for: op1) ?? barItem?.image(for: .normal)
- let h = barItem?.image(for: op2)
-
- setImage(n, for: .normal)
- setImage(h, for: .highlighted)
-
- if animated {
- _addAnimation("selected")
- }
-
- _selected = selected
- }
-
- private func _init() {
- addTarget(self, action: #selector(_touchHandler), for: .touchUpInside)
- }
-
- private func _addAnimation(_ key: String) {
- let ani = CATransition()
-
- ani.duration = 0.35
- ani.fillMode = CAMediaTimingFillMode.backwards
- ani.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
- ani.type = CATransitionType.fade
- ani.subtype = CATransitionSubtype.fromTop
-
- layer.add(ani, forKey: key)
- }
- private func _setHighlighted(_ highlighted: Bool, animated: Bool) {
- //logger.trace(highlighted)
- // 检查高亮的时候有没有设置图片, 如果有关闭系统的变透明效果
- if barItem?.image(for: [(isSelected ? .selected : .normal), .highlighted]) != nil {
- imageView?.alpha = 1
- }
- if animated {
- _addAnimation("highlighted")
- }
- }
-
- func _updateBarItem(_ item: SAIInputItem) {
-
- let states: [UIControl.State] = [
- [.normal],
- [.highlighted],
- [.disabled],
- [.selected, .normal],
- [.selected, .highlighted],
- [.selected, .disabled]
- ]
-
- tag = item.tag
- isEnabled = item.enabled
- imageEdgeInsets = item.imageInsets
-
- tintColor = item.tintColor
- backgroundColor = item.backgroundColor
-
- if let font = item.font {
- titleLabel?.font = font
- }
-
- states.forEach {
- setTitle(item.title(for: $0), for: $0)
- setTitleColor(item.titleColor(for: $0), for: $0)
- setTitleShadowColor(item.titleShadowColor(for: $0), for: $0)
- setAttributedTitle(item.attributedTitle(for: $0), for: $0)
- setImage(item.image(for: $0), for: $0)
- setBackgroundImage(item.backgroundImage(for: $0), for: $0)
- }
-
- setTitle(item.title, for: .normal)
- setImage(item.image, for: .normal)
- }
-
- @objc private func _touchHandler() {
- guard let barItem = barItem else {
- return
- }
- // delegate before the callback
- barItem.handler?(barItem)
-
- if !_selected {
- // select
- guard delegate?.barItem(shouldSelectFor: barItem) ?? true else {
- return
- }
- setSelected(selected: true, animated: true)
- delegate?.barItem(didSelectFor: barItem)
- } else {
- // Deselect
- guard delegate?.barItem(shouldDeselectFor: barItem) ?? true else {
- return
- }
- setSelected(selected: false, animated: true)
- delegate?.barItem(didDeselectFor: barItem)
- }
- }
-
- override init(frame: CGRect) {
- super.init(frame: frame)
- _init()
- }
- required init?(coder aDecoder: NSCoder) {
- super.init(coder: aDecoder)
- _init()
- }
- }
- internal protocol SAIInputItemViewDelegate: class {
-
- func barItem(shouldHighlightFor barItem: SAIInputItem) -> Bool
- func barItem(shouldDeselectFor barItem: SAIInputItem) -> Bool
- func barItem(shouldSelectFor barItem: SAIInputItem) -> Bool
-
- func barItem(didHighlightFor barItem: SAIInputItem)
- func barItem(didDeselectFor barItem: SAIInputItem)
- func barItem(didSelectFor barItem: SAIInputItem)
-
- }
|