Skip to content

Commit

Permalink
Merge branch 'MUToastAddButtons'
Browse files Browse the repository at this point in the history
  • Loading branch information
Loïc GRIFFIE committed Jun 27, 2019
2 parents 2bf030f + 1953b79 commit 3af9d07
Show file tree
Hide file tree
Showing 17 changed files with 169 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//: [Previous](@previous)

import UIKit
import PlaygroundSupport
import Sejima

MUToast.appearance().displayDuration = 0
MUToast.appearance().cornerRadius = 4
MUToast.appearance().titleColor = .white
MUToast.appearance().backgroundColor = .black
MUToast.appearance().indicatorColor = .red
MUToast.appearance().indicatorWidth = 10
MUToast.appearance().detailColor = .white

MUButton.appearance().borderWidth = 2
MUButton.appearance().cornerRadius = 4.0

// Global View

let vc = UIViewController()
vc.view.backgroundColor = .lightGray
vc.view.frame = CGRect(x: 0, y: 0, width: 375, height: 667)

let toast = MUToast()
toast.icon = #imageLiteral(resourceName: "reddit")
toast.buttonHeight = 30.0
toast.spacing = 8
toast.buttonSpacing = 16
toast.displayPosition = .bottom
toast.title = "Sorry, can't reach Reddit"
toast.titleFont = .boldSystemFont(ofSize: 18)
toast.detail = "Sorry, can't reach Reddit. Sorry, can't reach Reddit. Sorry, can't reach Reddit. Sorry, can't reach Reddit. Sorry, can't reach Reddit. Sorry, can't reach Reddit. Sorry, can't reach Reddit."
toast.detailFont = .systemFont(ofSize: 14)
toast.show(in: vc, onTap: {
print("toast has been tapped")
}, completion: { dismiss in
print("toast has been dismissed > ", dismiss)
})

let cancel = MUButton()
cancel.title = "CANCEL"
cancel.titleFont = .boldSystemFont(ofSize: 14)
cancel.buttonBackgroundColor = .clear
cancel.borderColor = .orange

let okay = MUButton()
okay.title = "OKAY"
okay.titleFont = .boldSystemFont(ofSize: 14)
okay.buttonBackgroundColor = .red
okay.borderColor = .red

toast.add(view: cancel) { (button, index) in
print("Button at index \(index) did tap")
}
toast.add(view: okay) { (button, index) in
print("Button at index \(index) did tap")
}

PlaygroundPage.current.liveView = vc

//: [Next](@next)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Sample/Playground.playground/Resources/reddit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions Sample/Playground.playground/contents.xcplayground
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@
<page name='MUBarGraph'/>
<page name='MUDatePicker'/>
<page name='MUButton'/>
<page name='RedditToast'/>
</pages>
</playground>
23 changes: 23 additions & 0 deletions Sample/Source/Assets.xcassets/reddit.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "reddit.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "[email protected]",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "[email protected]",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Sejima/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.6.0</string>
<string>0.6.1</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
</dict>
Expand Down
9 changes: 9 additions & 0 deletions Sejima/SejimaTests/MUToastTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class MUToastTests: XCTestCase {
XCTAssertEqual(toast.displayPriority, .info)
XCTAssertEqual(toast.horizontalPadding, 16.0)
XCTAssertEqual(toast.verticalPadding, 16.0)

XCTAssertEqual(toast.buttonSpacing, 16.0)
XCTAssertEqual(toast.buttonHeight, 0.0)
}

func testCustomValues() {
Expand Down Expand Up @@ -74,6 +77,9 @@ class MUToastTests: XCTestCase {
toast.horizontalPadding = 20.0
toast.verticalPadding = 20.0

toast.buttonSpacing = 16.0
toast.buttonHeight = 30.0

XCTAssertEqual(toast.cornerRadius, 4.0)

XCTAssertEqual(toast.title, "Title")
Expand All @@ -100,6 +106,9 @@ class MUToastTests: XCTestCase {
XCTAssertEqual(toast.displayPriority, .alert)
XCTAssertEqual(toast.horizontalPadding, 20.0)
XCTAssertEqual(toast.verticalPadding, 20.0)

XCTAssertEqual(toast.buttonSpacing, 16.0)
XCTAssertEqual(toast.buttonHeight, 30.0)
}

func testShow() {
Expand Down
6 changes: 4 additions & 2 deletions Sejima/Source/MUHeader/MUHeader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ open class MUHeader: MUNibView {
@IBInspectable open var title: String = "" {
didSet {
titleLabel.text = title
labelsSpacing.constant = detail.isEmpty ? 0 : spacing
}
}

Expand All @@ -45,6 +46,7 @@ open class MUHeader: MUNibView {
@IBInspectable open var detail: String = "" {
didSet {
detailLabel.text = detail
labelsSpacing.constant = detail.isEmpty ? 0 : spacing
}
}

Expand Down Expand Up @@ -97,14 +99,14 @@ open class MUHeader: MUNibView {
/// Return the height the header will have if constraint with this width.
open func expectedHeight(for width: CGFloat) -> CGFloat {
let size = CGSize(width: width, height: .greatestFiniteMagnitude)
return titleLabel.sizeThatFits(size).height + spacing + detailLabel.sizeThatFits(size).height
return titleLabel.sizeThatFits(size).height + labelsSpacing.constant + detailLabel.sizeThatFits(size).height
}

/// Return the size with a force sizeToFit (for unit tests only)
internal func debugSize() -> CGSize {
titleLabel.sizeToFit()
detailLabel.sizeToFit()
return CGSize(width: max(titleLabel.bounds.width, detailLabel.bounds.width),
height: titleLabel.bounds.height + spacing + detailLabel.bounds.height)
height: titleLabel.bounds.height + labelsSpacing.constant + detailLabel.bounds.height)
}
}
60 changes: 54 additions & 6 deletions Sejima/Source/MUToast/MUToast.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,16 @@ import UIKit

/// Class that define a card (title, description, indicator and image) with screen animation.
@IBDesignable
open class MUToast: MUNibView {
open class MUToast: MUNibView { // swiftlint:disable:this type_body_length
@IBOutlet private var markerView: UIView!
@IBOutlet private var imageView: UIImageView!
@IBOutlet private var header: MUHeader!
@IBOutlet private var buttons: UIStackView!

// Buttons inset constraint
@IBOutlet private var buttonsHeight: NSLayoutConstraint!
@IBOutlet private var buttonsTop: NSLayoutConstraint!
@IBOutlet private var buttonsBottom: NSLayoutConstraint!

// Image inset constraint
@IBOutlet private var markerWidth: NSLayoutConstraint!
Expand All @@ -24,11 +30,11 @@ open class MUToast: MUNibView {

// Labels inset constraints
@IBOutlet private var labelsTop: NSLayoutConstraint!
@IBOutlet private var labelsBottom: NSLayoutConstraint!
@IBOutlet private var labelsLeading: NSLayoutConstraint!
@IBOutlet private var labelsTrailing: NSLayoutConstraint!

private var onTapBlock: (() -> Void)?
private var onButtonTapBlock = [((button: MUButton, index: Int) -> Void)?]()

// MARK: - Background

Expand Down Expand Up @@ -143,14 +149,14 @@ open class MUToast: MUNibView {
@IBInspectable open var headerVerticalPadding: CGFloat = 16.0 {
didSet {
labelsTop.constant = headerVerticalPadding
labelsBottom.constant = headerVerticalPadding
buttonsBottom.constant = headerVerticalPadding
}
}

// MARK: - ImageView

/// Returns the image of the toast.
@IBInspectable open dynamic var icon: UIImage? = nil {
@IBInspectable open var icon: UIImage? = nil {
didSet {
imageView.image = icon

Expand Down Expand Up @@ -212,6 +218,23 @@ open class MUToast: MUNibView {
/// The toast’s vertical padding.
@IBInspectable open var verticalPadding: CGFloat = 16.0

// MARK: - Buttons layout

/// The buttons horizontal spacing spacing.
@IBInspectable open var buttonSpacing: CGFloat = 16.0 {
didSet {
buttons.spacing = buttonSpacing
buttonsTop.constant = buttonHeight > 0 ? buttonSpacing : 0
}
}

/// The buttons height.
@IBInspectable open dynamic var buttonHeight: CGFloat = 0.0 {
didSet {
buttonsHeight.constant = buttonHeight
}
}

// MARK: - Life cycle

/// Default setup to load the view from a xib file.
Expand Down Expand Up @@ -244,6 +267,16 @@ open class MUToast: MUNibView {
hidingAnimation(completion)
}

// MARK: - Public functions

public func add(view: UIView, tapBlock: ((_ button: MUButton, _ index: Int) -> Void)? = nil) {
buttons.addArrangedSubview(view)

guard let button = view as? MUButton, tapBlock != nil else { return }
button.delegate = self
onButtonTapBlock.append(tapBlock)
}

// MARK: - Private IBAction functions

@IBAction private func didTap(_ sender: UITapGestureRecognizer) {
Expand Down Expand Up @@ -274,12 +307,20 @@ open class MUToast: MUNibView {
private func expectedSize(in width: CGFloat) -> CGSize {
var size = CGSize(width: width - 2.0 * horizontalPadding, height: 0.0)

let headerWidth = size.width - iconLeftPadding - iconWidth - 2.0 * headerHorizontalPadding
var headerWidth = size.width - 2.0 * headerHorizontalPadding
if icon != nil {
headerWidth -= iconLeftPadding + iconWidth * 2
}

var headerHeight = header.expectedHeight(for: headerWidth)
if headerHeight < iconWidth {
if headerHeight < iconWidth, icon != nil {
headerHeight = iconWidth
}

if buttonHeight > 0 {
headerHeight += buttonHeight + headerVerticalPadding
}

size.height = headerHeight + 2.0 * headerVerticalPadding

return size
Expand Down Expand Up @@ -370,3 +411,10 @@ open class MUToast: MUNibView {
})
}
}

extension MUToast: MUButtonDelegate {
public func didTap(button: MUButton) {
guard let idx = buttons.arrangedSubviews.firstIndex(of: button) else { return }
onButtonTapBlock[idx]?(button, idx)
}
} // swiftlint:disable:this file_length
20 changes: 16 additions & 4 deletions Sejima/Source/MUToast/MUToast.xib
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="MUToast" customModule="Sejima" customModuleProvider="target">
<connections>
<outlet property="buttons" destination="aiJ-zc-nb2" id="ye1-bS-aNB"/>
<outlet property="buttonsBottom" destination="qps-4v-pic" id="maN-Zw-xEJ"/>
<outlet property="buttonsHeight" destination="ogx-OC-7rE" id="biQ-sZ-Xn1"/>
<outlet property="buttonsTop" destination="whP-7u-oQ3" id="IeB-Da-QDv"/>
<outlet property="header" destination="xCF-DK-RMr" id="90C-kR-3bU"/>
<outlet property="imageLeading" destination="IcN-KN-rid" id="Uqi-jR-SB9"/>
<outlet property="imageView" destination="Pq6-sz-WaI" id="2A3-Cg-D93"/>
<outlet property="imageWidth" destination="t1J-JV-PBc" id="zK7-ED-3od"/>
<outlet property="labelsBottom" destination="a2L-E5-99Q" id="rgf-VJ-U7a"/>
<outlet property="labelsLeading" destination="waw-DK-JvO" id="jPU-Dh-4Ns"/>
<outlet property="labelsTop" destination="wVf-kg-UQA" id="wji-Fb-lNL"/>
<outlet property="labelsTrailing" destination="vi4-go-gmO" id="vbw-3k-urI"/>
Expand Down Expand Up @@ -51,21 +54,30 @@
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillProportionally" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="aiJ-zc-nb2">
<rect key="frame" x="21" y="104" width="338" height="0.0"/>
<constraints>
<constraint firstAttribute="height" id="ogx-OC-7rE"/>
</constraints>
</stackView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<gestureRecognizers/>
<constraints>
<constraint firstItem="aiJ-zc-nb2" firstAttribute="leading" secondItem="xCF-DK-RMr" secondAttribute="leading" id="6ow-gM-6Vm"/>
<constraint firstItem="2Rf-A7-efj" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="7sJ-na-lTf"/>
<constraint firstItem="Pq6-sz-WaI" firstAttribute="leading" secondItem="2Rf-A7-efj" secondAttribute="trailing" id="IcN-KN-rid"/>
<constraint firstItem="xCF-DK-RMr" firstAttribute="height" relation="greaterThanOrEqual" secondItem="Pq6-sz-WaI" secondAttribute="height" id="NM4-RQ-hZ3"/>
<constraint firstItem="xCF-DK-RMr" firstAttribute="height" relation="greaterThanOrEqual" secondItem="Pq6-sz-WaI" secondAttribute="height" priority="750" id="NM4-RQ-hZ3"/>
<constraint firstAttribute="bottom" secondItem="2Rf-A7-efj" secondAttribute="bottom" id="XTB-pV-3Gf"/>
<constraint firstAttribute="bottom" secondItem="xCF-DK-RMr" secondAttribute="bottom" constant="16" id="a2L-E5-99Q"/>
<constraint firstItem="xCF-DK-RMr" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="dQC-YE-HYw"/>
<constraint firstItem="xCF-DK-RMr" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" priority="750" id="dQC-YE-HYw"/>
<constraint firstItem="Pq6-sz-WaI" firstAttribute="top" secondItem="xCF-DK-RMr" secondAttribute="top" id="hF1-Dv-NPb"/>
<constraint firstItem="2Rf-A7-efj" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="kec-bh-ymb"/>
<constraint firstAttribute="bottom" secondItem="aiJ-zc-nb2" secondAttribute="bottom" constant="16" id="qps-4v-pic"/>
<constraint firstItem="aiJ-zc-nb2" firstAttribute="trailing" secondItem="xCF-DK-RMr" secondAttribute="trailing" id="sqM-7T-RQV"/>
<constraint firstAttribute="trailing" secondItem="xCF-DK-RMr" secondAttribute="trailing" constant="16" id="vi4-go-gmO"/>
<constraint firstItem="xCF-DK-RMr" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="16" id="wVf-kg-UQA"/>
<constraint firstItem="xCF-DK-RMr" firstAttribute="leading" secondItem="Pq6-sz-WaI" secondAttribute="trailing" constant="16" id="waw-DK-JvO"/>
<constraint firstItem="aiJ-zc-nb2" firstAttribute="top" secondItem="xCF-DK-RMr" secondAttribute="bottom" id="whP-7u-oQ3"/>
</constraints>
<nil key="simulatedTopBarMetrics"/>
<nil key="simulatedBottomBarMetrics"/>
Expand Down

0 comments on commit 3af9d07

Please sign in to comment.