Skip to content

Commit

Permalink
Merge pull request #2 from teambition/feature/support-section
Browse files Browse the repository at this point in the history
DropdownMenu support section
  • Loading branch information
suricforever authored Oct 10, 2016
2 parents b65788b + 1eed57c commit b100f4d
Show file tree
Hide file tree
Showing 10 changed files with 234 additions and 28 deletions.
4 changes: 4 additions & 0 deletions DropdownMenu.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
4A076B271DAA32BF004BCBE4 /* SectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A076B261DAA32BF004BCBE4 /* SectionHeader.swift */; };
AC28BA811D5BAB25004F1663 /* DropUpMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC28BA801D5BAB25004F1663 /* DropUpMenu.swift */; };
AC4C1D5C1CF8325B006E36F5 /* DropdownItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4C1D5B1CF8325B006E36F5 /* DropdownItem.swift */; };
ACE6DB701CF74183005C6667 /* DropdownMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = ACE6DB6F1CF74183005C6667 /* DropdownMenu.h */; settings = {ATTRIBUTES = (Public, ); }; };
Expand All @@ -26,6 +27,7 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
4A076B261DAA32BF004BCBE4 /* SectionHeader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionHeader.swift; sourceTree = "<group>"; };
AC28BA801D5BAB25004F1663 /* DropUpMenu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DropUpMenu.swift; sourceTree = "<group>"; };
AC4C1D5B1CF8325B006E36F5 /* DropdownItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DropdownItem.swift; sourceTree = "<group>"; };
ACE6DB6C1CF74183005C6667 /* DropdownMenu.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DropdownMenu.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -81,6 +83,7 @@
ACE6DBC01CF74256005C6667 /* DropdownMenu.swift */,
AC28BA801D5BAB25004F1663 /* DropUpMenu.swift */,
AC4C1D5B1CF8325B006E36F5 /* DropdownItem.swift */,
4A076B261DAA32BF004BCBE4 /* SectionHeader.swift */,
ACE6DB711CF74183005C6667 /* Info.plist */,
);
path = DropdownMenu;
Expand Down Expand Up @@ -208,6 +211,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4A076B271DAA32BF004BCBE4 /* SectionHeader.swift in Sources */,
ACE6DBC11CF74256005C6667 /* DropdownMenu.swift in Sources */,
AC28BA811D5BAB25004F1663 /* DropUpMenu.swift in Sources */,
AC4C1D5C1CF8325B006E36F5 /* DropdownItem.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>ACE6DB6B1CF74183005C6667</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>ACE6DB751CF74183005C6667</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
type = "0"
version = "2.0">
</Bucket>
10 changes: 10 additions & 0 deletions DropdownMenu/DropdownItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,13 @@ open class DropdownItem {
self.accessoryImage = accessoryImage
}
}

public struct DropdownSection {
public var sectionIdentifier: String
public var items: [DropdownItem]

public init (sectionIdentifier: String, items: [DropdownItem]) {
self.items = items
self.sectionIdentifier = sectionIdentifier
}
}
72 changes: 59 additions & 13 deletions DropdownMenu/DropdownMenu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ public extension DropdownMenuDelegate {

open class DropdownMenu: UIView {
fileprivate weak var navigationController: UINavigationController!
fileprivate var items: [DropdownItem] = []
fileprivate var selectedRow: Int
fileprivate var sections: [DropdownSection] = []
fileprivate var selectedIndexPath: IndexPath
open var tableView: UITableView!
fileprivate var barCoverView: UIView!
fileprivate var isShow = false
Expand All @@ -37,22 +37,27 @@ open class DropdownMenu: UIView {
open var backgroudBeginColor: UIColor = UIColor.black.withAlphaComponent(0)
open var backgroudEndColor = UIColor(white: 0, alpha: 0.4)
open var rowHeight: CGFloat = 50
open var sectionHeaderHeight: CGFloat = 44
open var tableViewHeight: CGFloat = 0
open var defaultBottonMargin: CGFloat = 150
open var textColor: UIColor = UIColor(red: 56.0/255.0, green: 56.0/255.0, blue: 56.0/255.0, alpha: 1.0)
open var highlightColor: UIColor = UIColor(red: 3.0/255.0, green: 169.0/255.0, blue: 244.0/255.0, alpha: 1.0)
open var tableViewBackgroundColor: UIColor = UIColor(red: 242.0/255.0, green: 242.0/255.0, blue: 242.0/255.0, alpha: 1.0)
open var tableViewSeperatorColor = UIColor(red: 217.0/255.0, green: 217.0/255.0, blue: 217.0/255.0, alpha: 1.0)
open var displaySelected: Bool = true
open var displaySectionHeader: Bool = false

// section header sytle
open var sectionHeaderStyle: SectionHeaderStyle = SectionHeaderStyle()

required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

public init(navigationController: UINavigationController, items: [DropdownItem], selectedRow: Int = 0) {
self.navigationController = navigationController
self.items = items
self.selectedRow = selectedRow
self.sections = [DropdownSection(sectionIdentifier: "", items: items)]
self.selectedIndexPath = IndexPath(row: selectedRow, section: 0)

super.init(frame: CGRect.zero)

Expand All @@ -63,6 +68,22 @@ open class DropdownMenu: UIView {

NotificationCenter.default.addObserver(self, selector: #selector(self.updateForOrientationChange(_:)), name: NSNotification.Name.UIApplicationWillChangeStatusBarOrientation, object: nil)
}

public init(navigationController: UINavigationController, sections: [DropdownSection], selectedIndexPath: IndexPath = IndexPath(row: 0, section: 0), dispalySectionHeader: Bool = true, sectionHeaderStyle: SectionHeaderStyle = SectionHeaderStyle()) {
self.navigationController = navigationController
self.sections = sections
self.selectedIndexPath = selectedIndexPath
self.displaySectionHeader = dispalySectionHeader

super.init(frame: CGRect.zero)

clipsToBounds = true
setupGestureView()
setupTableView()
setupTopSeperatorView()

NotificationCenter.default.addObserver(self, selector: #selector(self.updateForOrientationChange(_:)), name: NSNotification.Name.UIApplicationWillChangeStatusBarOrientation, object: nil)
}

deinit {
NotificationCenter.default.removeObserver(self)
Expand Down Expand Up @@ -110,7 +131,7 @@ open class DropdownMenu: UIView {
}

fileprivate func setupTableView() {
tableViewHeight = CGFloat(items.count) * rowHeight
tableViewHeight = tableviewHeight()
let navigationBarFrame: CGRect = navigationController.navigationBar.frame
let maxHeight = navigationController.view.frame.height - navigationBarFrame.height + navigationBarFrame.origin.y - defaultBottonMargin
if tableViewHeight > maxHeight {
Expand Down Expand Up @@ -145,6 +166,17 @@ open class DropdownMenu: UIView {
barCoverView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(hideMenu)))
}

fileprivate func tableviewHeight() -> CGFloat {
var height: CGFloat = 0
if displaySectionHeader {
height += sectionHeaderHeight * CGFloat(sections.count)
}
for section in sections {
height += CGFloat(section.items.count) * rowHeight
}
return height
}

open func showMenu(isOnNavigaitionView: Bool = false) {
if isShow {
hideMenu()
Expand Down Expand Up @@ -201,15 +233,19 @@ open class DropdownMenu: UIView {
}

extension DropdownMenu: UITableViewDataSource {
public func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}

public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
return sections[section].items.count
}

public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let customCell = delegate?.dropdownMenu(self, cellForRowAt: indexPath) {
return customCell
}
let item = items[(indexPath as NSIndexPath).row]
let item = sections[indexPath.section].items[indexPath.row]
let cell = UITableViewCell(style: .default, reuseIdentifier: "dropdownMenuCell")

switch item.style {
Expand All @@ -229,7 +265,7 @@ extension DropdownMenu: UITableViewDataSource {

cell.textLabel?.text = item.title
cell.tintColor = highlightColor
if displaySelected && (indexPath as NSIndexPath).row == selectedRow {
if displaySelected && indexPath == selectedIndexPath {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
Expand All @@ -241,15 +277,19 @@ extension DropdownMenu: UITableViewDataSource {

return cell
}

public func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return displaySectionHeader ? sections[section].sectionIdentifier : nil
}
}

extension DropdownMenu: UITableViewDelegate {
public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return rowHeight
}

public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return CGFloat.leastNormalMagnitude
return displaySectionHeader ? sectionHeaderHeight : CGFloat.leastNormalMagnitude
}

public func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
Expand All @@ -258,11 +298,11 @@ extension DropdownMenu: UITableViewDelegate {

public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if displaySelected {
let item = items[(indexPath as NSIndexPath).row]
let item = sections[indexPath.section].items[indexPath.row]
if item.accessoryImage == nil {
let previousSelectedcell = tableView.cellForRow(at: IndexPath(row: selectedRow, section: 0))
let previousSelectedcell = tableView.cellForRow(at: selectedIndexPath)
previousSelectedcell?.accessoryType = .none
selectedRow = (indexPath as NSIndexPath).row
selectedIndexPath = indexPath
let cell = tableView.cellForRow(at: indexPath)
cell?.accessoryType = .checkmark
}
Expand All @@ -271,4 +311,10 @@ extension DropdownMenu: UITableViewDelegate {
hideMenu(isSelectAction: true)
delegate?.dropdownMenu(self, didSelectRowAt: indexPath)
}

public func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let sectionHeader = SectionHeader(style: sectionHeaderStyle)
sectionHeader.titleLabel.text = sections[section].sectionIdentifier
return sectionHeader
}
}
70 changes: 70 additions & 0 deletions DropdownMenu/SectionHeader.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//
// SectionHeader.swift
// DropdownMenu
//
// Created by WangWei on 2016/10/9.
// Copyright © 2016年 teambition. All rights reserved.
//

open class SectionHeader: UIView {
var titleLabel: UILabel!
var style: SectionHeaderStyle = SectionHeaderStyle()

convenience init(style: SectionHeaderStyle) {
self.init(frame: CGRect.zero)
self.style = style
commonInit()
}

override init(frame: CGRect) {
super.init(frame: frame)
}

required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}

func commonInit() {
titleLabel = UILabel()
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.font = style.font
titleLabel.textColor = style.textColor
backgroundColor = style.backgroundColor
addSubview(titleLabel)
updateTitleLabelConstraint()
}

func updateTitleLabelConstraint() {
let constraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|-leftPadding-[titleLabel]->=20-|", options: [], metrics: ["leftPadding": style.leftPadding], views: ["titleLabel": titleLabel])
addConstraints(constraints)
if style.shouldTitleCenterVertically {
let centerY = NSLayoutConstraint(item: titleLabel, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1.0, constant: 0)
addConstraint(centerY)
} else {
let vConstraints = NSLayoutConstraint(item: titleLabel, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1.0, constant: style.bottomPadding)
addConstraint(vConstraints)
}
}
}


public struct SectionHeaderStyle {

/// leftPadding for title label, default is `20`
public var leftPadding: CGFloat = 20
/// bottom padding for title label, default is `10`,
/// will be ignored when `shouldTitleCenterVertically` is `true`
public var bottomPadding: CGFloat = 10
/// should title label center in axis Y, default is `true`
public var shouldTitleCenterVertically: Bool = true

/// title label font, default is `UIFont.systemFont(ofSize: 14)`
public var font: UIFont = UIFont.systemFont(ofSize: 14)
/// title label textColor, default is A6A6A6
public var textColor: UIColor = UIColor(red: 166.0/255.0, green: 166.0/255.0, blue: 166.0/255.0, alpha: 1.0)
/// backgroundColor for header, default is F2F2F2
public var backgroundColor: UIColor = UIColor(red: 242.0/255.0, green: 242.0/255.0, blue: 242.0/255.0, alpha: 1.0)

public init() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>ACE6DB8E1CF741F6005C6667</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>ACE6DBA21CF741F6005C6667</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>ACE6DBAD1CF741F6005C6667</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
18 changes: 14 additions & 4 deletions DropdownMenuDemo/DropdownMenuDemo/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11201" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="bEP-BO-oRt">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11201" systemVersion="16A323" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="bEP-BO-oRt">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
Expand All @@ -18,15 +18,22 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="BzP-Ey-vYz">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="have sections" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="BzP-Ey-vYz">
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="25g-q9-wVt">
<connections>
<action selector="sectionSwitchValueChanged:" destination="BYZ-38-t0r" eventType="valueChanged" id="yt0-i8-kxP"/>
</connections>
</switch>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="BzP-Ey-vYz" firstAttribute="centerY" secondItem="8bC-Xf-vdC" secondAttribute="centerY" id="Q4n-FJ-PHj"/>
<constraint firstItem="25g-q9-wVt" firstAttribute="centerX" secondItem="BzP-Ey-vYz" secondAttribute="centerX" id="uiI-Kb-AoW"/>
<constraint firstItem="25g-q9-wVt" firstAttribute="top" secondItem="BzP-Ey-vYz" secondAttribute="bottom" constant="8" id="y3J-U1-nOz"/>
<constraint firstItem="BzP-Ey-vYz" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="zco-dm-bDh"/>
</constraints>
</view>
Expand All @@ -42,6 +49,9 @@
</connections>
</barButtonItem>
</navigationItem>
<connections>
<outlet property="sectionSwitch" destination="25g-q9-wVt" id="wk0-sS-ZvT"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
Expand Down Expand Up @@ -79,7 +89,7 @@
<rect key="frame" x="0.0" y="92" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="0qN-ja-FGY" id="TCk-ux-5Dk">
<frame key="frameInset" width="375" height="44"/>
<frame key="frameInset" width="375" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
</tableViewCellContentView>
</tableViewCell>
Expand Down
Loading

0 comments on commit b100f4d

Please sign in to comment.