Commit bdacb4a0 by Orkhan Alikhanov

Added RadioButtonGroup and CheckButtonGroup

parent 6f08ea16
......@@ -174,6 +174,9 @@
96E3C39A1D3A1CC20086A024 /* ErrorTextField.swift in Headers */ = {isa = PBXBuildFile; fileRef = 961F18E71CD93E3E008927C5 /* ErrorTextField.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96E3C39C1D3A1CC20086A024 /* Offset.swift in Headers */ = {isa = PBXBuildFile; fileRef = 968C99461D377849000074FF /* Offset.swift */; settings = {ATTRIBUTES = (Public, ); }; };
96F1A5531F24F17A001D8CAF /* TabsController.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96E09DC71F2287E50000B121 /* TabsController.swift */; settings = {ATTRIBUTES = (Public, ); }; };
9DE84D721FF0252600586C8B /* RadioButtonGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DE84D6F1FF0252500586C8B /* RadioButtonGroup.swift */; };
9DE84D731FF0252600586C8B /* BaseButtonGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DE84D701FF0252500586C8B /* BaseButtonGroup.swift */; };
9DE84D741FF0252600586C8B /* CheckButtonGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DE84D711FF0252500586C8B /* CheckButtonGroup.swift */; };
9DF352421FED20C900B2A11B /* BaseIconLayerButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DF352411FED20C900B2A11B /* BaseIconLayerButton.swift */; };
9DF352441FED20ED00B2A11B /* RadioButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DF352431FED20ED00B2A11B /* RadioButton.swift */; };
9DF352461FED210000B2A11B /* CheckButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DF352451FED210000B2A11B /* CheckButton.swift */; };
......@@ -288,6 +291,9 @@
96E09DC71F2287E50000B121 /* TabsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabsController.swift; sourceTree = "<group>"; };
96E3C3931D397AE90086A024 /* Material+UIView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Material+UIView.swift"; sourceTree = "<group>"; };
96F1DC871D654FDF0025F925 /* Material+CALayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Material+CALayer.swift"; sourceTree = "<group>"; };
9DE84D6F1FF0252500586C8B /* RadioButtonGroup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RadioButtonGroup.swift; sourceTree = "<group>"; };
9DE84D701FF0252500586C8B /* BaseButtonGroup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseButtonGroup.swift; sourceTree = "<group>"; };
9DE84D711FF0252500586C8B /* CheckButtonGroup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckButtonGroup.swift; sourceTree = "<group>"; };
9DF352411FED20C900B2A11B /* BaseIconLayerButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseIconLayerButton.swift; sourceTree = "<group>"; };
9DF352431FED20ED00B2A11B /* RadioButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButton.swift; sourceTree = "<group>"; };
9DF352451FED210000B2A11B /* CheckButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckButton.swift; sourceTree = "<group>"; };
......@@ -523,6 +529,7 @@
96264BE41D833C8400576F37 /* Bar */,
962DDD081D6FBBD0001C307C /* BottomTabBar */,
96BCB8031CB40F4B00C806FE /* Button */,
9DE84D6E1FF0250E00586C8B /* ButtonGroup */,
96BCB8021CB40F3B00C806FE /* Card */,
961154CA1F32999000A78D74 /* Chip */,
96BCB8051CB40F9C00C806FE /* Collection */,
......@@ -738,6 +745,16 @@
name = Animation;
sourceTree = "<group>";
};
9DE84D6E1FF0250E00586C8B /* ButtonGroup */ = {
isa = PBXGroup;
children = (
9DE84D701FF0252500586C8B /* BaseButtonGroup.swift */,
9DE84D6F1FF0252500586C8B /* RadioButtonGroup.swift */,
9DE84D711FF0252500586C8B /* CheckButtonGroup.swift */,
);
name = ButtonGroup;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
......@@ -948,6 +965,7 @@
965E81181DD4D5C800D61E4B /* Snackbar.swift in Sources */,
965E81191DD4D5C800D61E4B /* SnackbarController.swift in Sources */,
9618006D1F4D384200CD77A1 /* Material+UIViewController.swift in Sources */,
9DE84D741FF0252600586C8B /* CheckButtonGroup.swift in Sources */,
965E811A1DD4D5C800D61E4B /* StatusBarController.swift in Sources */,
965E811B1DD4D5C800D61E4B /* Switch.swift in Sources */,
965E811C1DD4D5C800D61E4B /* TabBar.swift in Sources */,
......@@ -959,6 +977,7 @@
965E80E71DD4C55200D61E4B /* Material+UIView.swift in Sources */,
965E80E81DD4C55200D61E4B /* Material+CALayer.swift in Sources */,
965E80E91DD4C55200D61E4B /* Material+String.swift in Sources */,
9DE84D731FF0252600586C8B /* BaseButtonGroup.swift in Sources */,
965E80F71DD4D59500D61E4B /* Card.swift in Sources */,
965E80EA1DD4C55200D61E4B /* Material+UIFont.swift in Sources */,
965E80EB1DD4C55200D61E4B /* Material+UIImage.swift in Sources */,
......@@ -969,6 +988,7 @@
9DF352421FED20C900B2A11B /* BaseIconLayerButton.swift in Sources */,
966C17731F0439F600D3E83C /* Material+MotionAnimation.swift in Sources */,
965E80E51DD4C53300D61E4B /* PulseAnimation.swift in Sources */,
9DE84D721FF0252600586C8B /* RadioButtonGroup.swift in Sources */,
965E80FE1DD4D59500D61E4B /* ToolbarController.swift in Sources */,
96328B971E05C0BB009A4C90 /* TableView.swift in Sources */,
965E80F81DD4D59500D61E4B /* ImageCard.swift in Sources */,
......
//
// BaseButtonGroup.swift
// Material
//
// Created by Orkhan Alikhanov on 12/24/17.
// Copyright © 2017 CosmicMind, Inc. All rights reserved.
//
open class BaseButtonGroup<T: Button>: View {
open var buttons: [T] = [] {
didSet {
oldValue.forEach {
$0.removeFromSuperview()
$0.removeTarget(self, action: #selector(didTap(_:)), for: .touchUpInside)
}
prepareButtons()
grid.views = buttons
grid.axis.rows = buttons.count
}
}
public convenience init(buttons: [T]) {
self.init(frame: .zero)
defer { self.buttons = buttons } // defer allows didSet to be called
}
open override func prepare() {
super.prepare()
grid.axis.direction = .vertical
grid.axis.columns = 1
}
open override var intrinsicContentSize: CGSize { return sizeThatFits(bounds.size) }
open override func sizeThatFits(_ size: CGSize) -> CGSize {
let size = CGSize(width: size.width == 0 ? .greatestFiniteMagnitude : size.width, height: size.height == 0 ? .greatestFiniteMagnitude : size.height)
let availableW = size.width - grid.contentEdgeInsets.left - grid.contentEdgeInsets.right - grid.layoutEdgeInsets.left - grid.layoutEdgeInsets.right
var maxW: CGFloat = 0
buttons.forEach { maxW = max(maxW, $0.sizeThatFits(.init(width: availableW, height: .greatestFiniteMagnitude)).width) }
var h = grid.contentEdgeInsets.top + grid.contentEdgeInsets.bottom + grid.layoutEdgeInsets.top + grid.layoutEdgeInsets.bottom + CGFloat(buttons.count - 1) * grid.interimSpace
buttons.forEach { h += $0.sizeThatFits(.init(width: maxW, height: .greatestFiniteMagnitude)).height }
return CGSize(width: maxW + grid.contentEdgeInsets.left + grid.contentEdgeInsets.right + grid.layoutEdgeInsets.left + grid.layoutEdgeInsets.right, height: min(h, size.height))
}
open override func layoutSubviews() {
super.layoutSubviews()
grid.reload()
}
open func didTap(button: T, at index: Int) { }
@objc
private func didTap(_ sender: Button) {
guard let sender = sender as? T,
let index = buttons.index(of: sender)
else { return }
didTap(button: sender, at: index)
}
}
private extension BaseButtonGroup {
func prepareButtons() {
buttons.forEach {
addSubview($0)
$0.removeTarget(nil, action: nil, for: .allEvents)
$0.addTarget(self, action: #selector(didTap(_:)), for: .touchUpInside)
}
}
}
//
// CheckButtonGroup.swift
// Material
//
// Created by Orkhan Alikhanov on 12/24/17.
// Copyright © 2017 CosmicMind, Inc. All rights reserved.
//
open class CheckButtonGroup: BaseButtonGroup<CheckButton> {
public convenience init(titles: [String]) {
let buttons = titles.map { CheckButton(title: $0) }
self.init(buttons: buttons)
}
open var selecetedButtons: [CheckButton] {
return buttons.filter { $0.isSelected }
}
open var selectedIndices: [Int] {
return selecetedButtons.map { buttons.index(of: $0)! }
}
open override func didTap(button: CheckButton, at index: Int) {
button.setSelected(!button.isSelected, animated: true)
}
}
//
// RadioButtonGroup.swift
// Material
//
// Created by Orkhan Alikhanov on 12/24/17.
// Copyright © 2017 CosmicMind, Inc. All rights reserved.
//
open class RadioButtonGroup: BaseButtonGroup<RadioButton> {
public convenience init(titles: [String]) {
let buttons = titles.map { RadioButton(title: $0) }
self.init(buttons: buttons)
}
open var selectedButton: RadioButton? {
return buttons.first { $0.isSelected }
}
open var selectedIndex: Int {
guard let b = selectedButton else { return -1 }
return buttons.index(of: b)!
}
open override func didTap(button: RadioButton, at index: Int) {
let isAnimating = buttons.reduce(false) { $0 || $1.isAnimating }
guard !isAnimating else { return }
buttons.forEach { $0.setSelected($0 == button, animated: true) }
}
}
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