├── LICENSE
├── README.md
├── SwiftPopMenu.podspec
├── SwiftPopMenu
└── SwiftPopMenu.swift
├── SwiftPopMenuDemo
├── SwiftPopMenu.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ ├── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcuserdata
│ │ │ ├── MACBOOK.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ │ │ └── liyajun.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ │ ├── MACBOOK.xcuserdatad
│ │ └── xcschemes
│ │ │ ├── SwiftPopMenu.xcscheme
│ │ │ └── xcschememanagement.plist
│ │ └── liyajun.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
├── SwiftPopMenu
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── Shape.imageset
│ │ │ ├── Contents.json
│ │ │ ├── Shape.png
│ │ │ ├── Shape@2x.png
│ │ │ └── Shape@3x.png
│ │ ├── SignRule.imageset
│ │ │ ├── Contents.json
│ │ │ ├── SignRule.png
│ │ │ ├── SignRule@2x.png
│ │ │ └── SignRule@3x.png
│ │ └── saoyisao.imageset
│ │ │ ├── Contents.json
│ │ │ ├── saoyisao.png
│ │ │ ├── saoyisao@2x.png
│ │ │ └── saoyisao@3x.png
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── Info.plist
│ ├── SwiftPopMenuSrc
│ │ └── SwiftPopMenu.swift
│ └── ViewController.swift
└── SwiftPopMenuUITests
│ ├── Info.plist
│ └── SwiftPopMenuUITests.swift
├── img1.png
├── img2.png
├── img3.png
└── swiftPopMenu.gif
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2011-2016 SwiftPopMenu Software Foundation (https://github.com/TangledHusky/SwiftPopMenu)
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SwiftPopMenu 效果图:
2 |
3 |
4 |
5 |
6 |
7 | 功能:
8 | 只需要传入菜单箭头点位置、菜单宽度、数据源即可。
9 |
10 | 1、支持任意点弹出(点是基于整个屏幕位置)
11 | 2、会根据点位置自动计算菜单位置和高度
12 | 3、背景色、文字等属性支持自定义设置
13 | 4、easy自定义,有更多需求,可以直接在SwiftPopMenu.swift自己修改
14 |
15 |
16 | 导入项目:
17 |
18 | - pods导入:pod 'SwiftPopMenu'
19 |
20 | - 文件导入:下载Demo,导入SwiftPopMenu.swift文件即可
21 |
22 | - 代码现已支持 Swift5 (2.x已支持swift5,1.x支持swift3)
23 |
24 |
25 | 使用介绍:
26 |
27 | import SwiftPopMenu
28 |
29 |
30 | 1、初始化Init
31 |
32 |
33 | ///初始化菜单
34 | init(menuWidth:CGFloat, //菜单宽度(高度不需要传,会根据item高*item数量自动计算)
35 | arrow:CGPoint, //箭头点位置是基于整个屏幕的位置
36 | datas:[(icon:String,title:String)], //数据源数组,icon没有就传空
37 | configures:[SwiftPopMenuConfigure] = [] //配置信息,可不传,不传采用默认值
38 | ) {}
39 |
40 |
41 |
42 | 2、显示与移除
43 |
44 | popMenu.show()
45 |
46 | popMenu.dismiss()
47 |
48 |
49 | 3、点击事件,提供两种方式
50 |
51 | - block回调处理
52 | - delegate代理处理
53 |
54 | 4、参数配置(使用时可不传)
55 |
56 | public enum SwiftPopMenuConfigure {
57 | case PopMenuTextFont(UIFont) //菜单文字字体,默认systemFont(ofSize: 17)
58 | case PopMenuTextColor(UIColor) //菜单文字颜色,默认black
59 | case PopMenuBackgroudColor(UIColor) //菜单背景色,默认white
60 | case popMenuCornorRadius(CGFloat) //菜单圆角,默认6
61 | case popMenuItemHeight(CGFloat) //菜单内单行高度(非整个menu高度),默认44.0
62 | case popMenuSplitLineColor(UIColor) //菜单分割线颜色,默认(222,222,222)
63 | case popMenuIconLeftMargin(CGFloat) //icon左间距,默认15
64 | case popMenuMargin(CGFloat) //菜单与屏幕边距,默认10
65 | case popMenuAlpha(CGFloat) //菜单背景透明度,默认0.3
66 | }
67 |
68 |
69 | 完整示例代码:
70 |
71 | var popMenu:SwiftPopMenu!
72 |
73 |
74 | //数据源(icon可不填)
75 | let popData = [(icon:"saoyisao",title:"扫一扫"),
76 | (icon:"SignRule",title:"签到规则"),
77 | (icon:"saoyisao",title:"扫一扫"),
78 | (icon:"SignRule",title:"签到规则")]
79 |
80 | //设置Parameter(可不写)
81 | let parameters:[SwiftPopMenuConfigure] = [
82 | .PopMenuTextColor(UIColor.black),
83 | .popMenuItemHeight(44),
84 | .PopMenuTextFont(UIFont.systemFont(ofSize: 18))
85 | ]
86 |
87 | //init (注意:arrow点是基于屏幕的位置)
88 | popMenu = SwiftPopMenu(menuWidth: 150, arrow: CGPoint(x: 100, y: 100), datas: popData,configures: parameters)
89 |
90 | //click
91 | popMenu.didSelectMenuBlock = { [weak self](index:Int)->Void in
92 | print("block select \(index)")
93 | self?.popMenu = nil
94 | }
95 |
96 | //show
97 | popMenu.show()
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/SwiftPopMenu.podspec:
--------------------------------------------------------------------------------
1 |
2 | Pod::Spec.new do |s|
3 |
4 |
5 |
6 | s.name = "SwiftPopMenu"
7 | s.version = "2.0.2"
8 | s.summary = "support swift5 ,any point pop"
9 | s.swift_version = '5.0'
10 |
11 | s.description = "优化使用方式 support swift5 ,easy use SwiftPopMenu on iOS"
12 |
13 | s.homepage = "https://github.com/TangledHusky/SwiftPopMenu"
14 |
15 |
16 | s.license = { :type => "MIT", :file => "LICENSE" }
17 |
18 |
19 | s.author = { "TangledHusky" => "994825763@qq.com" }
20 | s.platform = :ios, "8.0"
21 |
22 |
23 |
24 | s.source = { :git => "https://github.com/TangledHusky/SwiftPopMenu.git", :tag => "v#{s.version}" }
25 |
26 |
27 |
28 | s.source_files = "SwiftPopMenu/*.{swift}"
29 |
30 |
31 |
32 |
33 | end
34 |
--------------------------------------------------------------------------------
/SwiftPopMenu/SwiftPopMenu.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PopView.swift
3 | // TestSwift
4 | //
5 | // Created by lyj on 16/5/7.
6 | // Copyright © 2016年 zyyj. All rights reserved.
7 | /*
8 | GitHub:https://github.com/TangledHusky/SwiftPopMenu
9 |
10 | 功能:
11 | 只需要传入菜单箭头点位置、菜单宽度、数据源即可。
12 |
13 | 1、支持任意点弹出(点是基于整个屏幕位置)
14 | 2、会根据点位置自动计算菜单位置
15 | 3、背景色、文字等支持自定义设置
16 | 4、菜单最大宽度=屏幕-边距 最大高度=屏幕高度一半
17 | */
18 |
19 | import UIKit
20 |
21 | public protocol SwiftPopMenuDelegate :NSObjectProtocol{
22 | func swiftPopMenuDidSelectIndex(index:Int)
23 | }
24 |
25 |
26 | public enum SwiftPopMenuConfigure {
27 | case PopMenuTextFont(UIFont) //菜单文字字体
28 | case PopMenuTextColor(UIColor) //菜单文字颜色
29 | case PopMenuBackgroudColor(UIColor) //菜单背景色
30 | case popMenuCornorRadius(CGFloat) //菜单圆角
31 | case popMenuItemHeight(CGFloat) //菜单行高度
32 | case popMenuSplitLineColor(UIColor) //菜单分割线颜色
33 | case popMenuIconLeftMargin(CGFloat) //icon左间距
34 | case popMenuMargin(CGFloat) //菜单与屏幕边距
35 | case popMenuAlpha(CGFloat) //菜单背景透明度
36 | }
37 |
38 | public class SwiftPopMenu: UIView {
39 |
40 | //delegate
41 | weak var delegate : SwiftPopMenuDelegate?
42 | //block
43 | public var didSelectMenuBlock:((_ index:Int)->Void)?
44 |
45 | let KScrW:CGFloat = UIScreen.main.bounds.size.width
46 | let KScrH:CGFloat = UIScreen.main.bounds.size.height
47 |
48 |
49 |
50 | ///* ----------------------- 外部参数 通过configure设置 ---------------------------- */
51 | //区域外背景透明度
52 | private var popMenuOutAlpha:CGFloat = 0.3
53 | //背景色
54 | private var popMenuBgColor:UIColor = UIColor.white
55 | //圆角弧度
56 | private var popMenuCornorRadius:CGFloat = 6
57 | //文字颜色
58 | private var popMenuTextColor:UIColor = UIColor.black
59 | //字体大小等
60 | private var popMenuTextFont:UIFont = UIFont.systemFont(ofSize: 17)
61 | //菜单高度
62 | private var popMenuItemHeight:CGFloat = 44.0
63 | //菜单分割线颜色
64 | private var popMenuSplitLineColor:UIColor = UIColor(red: 222/255.0, green: 222/255.0, blue: 222/255.0, alpha: 0.5)
65 | //icon左间距
66 | private var popMenuIconLeftMargin:CGFloat = 15
67 | //菜单与屏幕边距
68 | private var popMenuMargin:CGFloat = 10
69 |
70 | ///* ----------------------- 外部参数 over------------------------------------------ */
71 |
72 | private var arrowPoint : CGPoint = CGPoint.zero //小箭头位置
73 | private var arrowViewWidth : CGFloat = 15 //三角箭头宽
74 | private var arrowViewHeight : CGFloat = 10 //三角箭头高
75 | private var popData:[(icon:String,title:String)]! //数据源
76 |
77 | static let cellID:String = "SwiftPopMenuCellID"
78 | private var myFrame:CGRect! //tableview frame
79 | private var arrowView : UIView! = nil
80 |
81 | var tableView:UITableView! = nil
82 |
83 |
84 |
85 | /// 初始化菜单
86 | ///
87 | /// - Parameters:
88 | /// - menuWidth: 菜单宽度
89 | /// - arrow: 箭头位置是popmenu相对整个屏幕的位置
90 | /// - datas: 数据源,icon允许传空,数据源没数据,不会显示菜单
91 | /// - configure: 配置信息,可不传
92 | public init(menuWidth:CGFloat,arrow:CGPoint,datas:[(icon:String,title:String)],configures:[SwiftPopMenuConfigure] = []) {
93 | super.init(frame: UIScreen.main.bounds)
94 | self.frame = UIScreen.main.bounds
95 | //读取配置
96 | configures.forEach { (config) in
97 | switch (config){
98 | case let .PopMenuTextFont(value):
99 | popMenuTextFont = value
100 | case let .PopMenuTextColor(value):
101 | popMenuTextColor = value
102 | case let .PopMenuBackgroudColor(value):
103 | popMenuBgColor = value
104 | case let .popMenuCornorRadius(value):
105 | popMenuCornorRadius = value
106 | case let .popMenuItemHeight(value):
107 | popMenuItemHeight = value
108 | case let .popMenuSplitLineColor(value):
109 | popMenuSplitLineColor = value
110 | case let .popMenuIconLeftMargin(value):
111 | popMenuIconLeftMargin = value
112 | case let .popMenuMargin(value):
113 | popMenuMargin = value
114 | case let .popMenuAlpha(value):
115 | popMenuOutAlpha = value
116 | }
117 | }
118 |
119 | popData = datas
120 | //设置myFrame size ,original会在后面计算
121 | myFrame = CGRect(x: 0, y: 0, width: menuWidth, height: popMenuItemHeight*CGFloat(popData.count))
122 | myFrame.size.height = min(KScrH/2, myFrame.height)
123 | myFrame.size.width = min(KScrW-popMenuMargin*2, myFrame.width)
124 |
125 | //设置肩头,与屏幕间隔10
126 | arrowPoint = arrow
127 | arrowPoint.x = max(popMenuMargin, min(arrowPoint.x, KScrW-popMenuMargin))
128 |
129 | }
130 |
131 | required public init?(coder aDecoder: NSCoder) {
132 | fatalError("init(coder:) has not been implemented")
133 | }
134 |
135 |
136 |
137 | func initViews() {
138 | self.backgroundColor = UIColor.black.withAlphaComponent(popMenuOutAlpha)
139 |
140 | let arrowPs = getArrowPoints()
141 | myFrame.origin = arrowPs.3
142 | let isarrowUP = arrowPs.4
143 | print(arrowPs)
144 | //箭头
145 | arrowView=UIView(frame: CGRect(x: myFrame.origin.x, y: isarrowUP ? myFrame.origin.y-arrowViewHeight : myFrame.origin.y+myFrame.height, width: myFrame.width, height: arrowViewHeight))
146 | let layer=CAShapeLayer()
147 | let path=UIBezierPath()
148 | path.move(to: arrowPs.0)
149 | path.addLine(to: arrowPs.1)
150 | path.addLine(to: arrowPs.2)
151 | layer.path=path.cgPath
152 | layer.fillColor = popMenuBgColor.cgColor
153 | arrowView.layer.addSublayer(layer)
154 | self.addSubview(arrowView)
155 |
156 | tableView=UITableView(frame: CGRect(x: myFrame.origin.x,y: myFrame.origin.y,width: myFrame.width,height: myFrame.height), style: .plain)
157 | tableView.register(SwiftPopMenuCell.classForCoder(), forCellReuseIdentifier: SwiftPopMenu.cellID)
158 | tableView.backgroundColor = popMenuBgColor
159 | tableView.layer.cornerRadius = popMenuCornorRadius
160 | tableView.separatorStyle = .none
161 | tableView.layer.masksToBounds = true
162 | tableView.delegate = self
163 | tableView.dataSource = self
164 | tableView.bounces = false
165 | UIView.animate(withDuration: 0.3) {
166 | self.addSubview(self.tableView)
167 | }
168 | }
169 |
170 |
171 | /// 计算箭头位置
172 | ///
173 | /// - Returns: (三角箭头顶,三角箭头左,三角箭头右,tableview 原点,是否箭头朝上)
174 | func getArrowPoints() -> (CGPoint,CGPoint,CGPoint,CGPoint,Bool) {
175 | if arrowPoint.x <= popMenuMargin {
176 | arrowPoint.x = popMenuMargin
177 | }
178 | if arrowPoint.x >= KScrW - popMenuMargin{
179 | arrowPoint.x = KScrW - popMenuMargin
180 | }
181 | var originalPoint = CGPoint.zero
182 |
183 | //箭头中间距离左边距离
184 | var arrowMargin:CGFloat = popMenuMargin
185 | if arrowPoint.x < KScrW/2{
186 | if (arrowPoint.x > myFrame.width/2) {
187 | arrowMargin = myFrame.width/2
188 | originalPoint = CGPoint(x: arrowPoint.x - myFrame.width/2, y: arrowPoint.y+arrowViewHeight)
189 | }else{
190 | arrowMargin = arrowPoint.x-popMenuMargin
191 | originalPoint = CGPoint(x: popMenuMargin, y: arrowPoint.y+arrowViewHeight)
192 | }
193 |
194 | }else{
195 |
196 | if (KScrW-arrowPoint.x) < myFrame.width/2{
197 | arrowMargin = (myFrame.width - KScrW + arrowPoint.x )
198 | originalPoint = CGPoint(x: KScrW-popMenuMargin-myFrame.width, y: arrowPoint.y+arrowViewHeight)
199 |
200 |
201 | }else{
202 | arrowMargin = myFrame.width/2
203 | originalPoint = CGPoint(x: arrowPoint.x-myFrame.width/2, y: arrowPoint.y+arrowViewHeight)
204 | }
205 | }
206 |
207 | //箭头朝上
208 | if (KScrH - arrowPoint.y) > myFrame.height{
209 |
210 | return (CGPoint(x: arrowMargin, y: 0),CGPoint(x: arrowMargin-arrowViewWidth/2, y: arrowViewHeight),CGPoint(x: arrowMargin+arrowViewWidth/2, y: arrowViewHeight),originalPoint,true)
211 |
212 | }else{
213 | originalPoint.y = arrowPoint.y-myFrame.height-arrowViewHeight
214 |
215 | return (CGPoint(x: arrowMargin, y: arrowViewHeight),CGPoint(x: arrowMargin-arrowViewWidth/2, y: 0),CGPoint(x: arrowMargin+arrowViewWidth/2, y: 0),originalPoint,false)
216 | }
217 |
218 | }
219 |
220 | }
221 |
222 |
223 |
224 | // MARK: - 页面显示、隐藏
225 | extension SwiftPopMenu{
226 |
227 | override public func touchesBegan(_ touches: Set, with event: UIEvent?) {
228 | if touches.first?.view != tableView{
229 | dismiss()
230 | }
231 | }
232 |
233 | public func show() {
234 | if popData.isEmpty{
235 | return
236 | }
237 | initViews()
238 | UIApplication.shared.keyWindow?.addSubview(self)
239 | }
240 |
241 | public func dismiss() {
242 | self.removeFromSuperview()
243 | }
244 |
245 | }
246 |
247 | // MARK: - UITableViewDataSource,UITableViewDelegate
248 | extension SwiftPopMenu : UITableViewDataSource,UITableViewDelegate{
249 |
250 | public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
251 | return popData.count
252 | }
253 |
254 | public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
255 | if popData.count>indexPath.row {
256 | let cell = tableView.dequeueReusableCell(withIdentifier: SwiftPopMenu.cellID) as! SwiftPopMenuCell
257 |
258 | let model = popData[indexPath.row]
259 | cell.setConfig(_txtColor: popMenuTextColor, _lineColor: popMenuSplitLineColor, _txtFont: popMenuTextFont, _iconLeft: popMenuIconLeftMargin)
260 | if indexPath.row == popData.count - 1 {
261 | cell.fill(iconName: model.icon, title: model.title, islast: true)
262 | }else{
263 | cell.fill(iconName: model.icon, title: model.title)
264 | }
265 | return cell
266 | }
267 |
268 | return UITableViewCell()
269 | }
270 |
271 | public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
272 | return popMenuItemHeight
273 | }
274 |
275 | public func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
276 | return 0.01
277 | }
278 |
279 | public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
280 | if self.delegate != nil{
281 | self.delegate?.swiftPopMenuDidSelectIndex(index: indexPath.row)
282 | }
283 | if didSelectMenuBlock != nil {
284 | didSelectMenuBlock!(indexPath.row)
285 | }
286 |
287 | dismiss()
288 | }
289 |
290 | }
291 |
292 |
293 |
294 | /// UITableViewCell
295 | class SwiftPopMenuCell: UITableViewCell {
296 | var iconImage:UIImageView!
297 | var lblTitle:UILabel!
298 | var line:UIView!
299 |
300 | //自定义属性
301 | var lineColor:UIColor = UIColor(red: 222/255.0, green: 222/255.0, blue: 222/255.0, alpha: 0.5)
302 | var txtColor:UIColor = UIColor.black
303 | var txtFont:UIFont = UIFont.systemFont(ofSize: 17)
304 | var iconLeft:CGFloat = 15
305 |
306 |
307 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
308 | super.init(style: style, reuseIdentifier: reuseIdentifier)
309 | self.backgroundColor = UIColor.clear
310 |
311 | iconImage = UIImageView()
312 | self.contentView.addSubview(iconImage)
313 | self.selectionStyle = .none
314 |
315 | lblTitle = UILabel()
316 | self.contentView.addSubview(lblTitle)
317 |
318 | line = UIView()
319 | self.contentView.addSubview(line)
320 | }
321 |
322 |
323 | required init?(coder aDecoder: NSCoder) {
324 | fatalError("init(coder:) has not been implemented")
325 | }
326 |
327 |
328 | func fill(iconName:String,title:String,islast:Bool = false) {
329 | iconImage.image = UIImage(named: iconName)
330 | lblTitle.text = title
331 | line.isHidden = islast
332 | }
333 |
334 | func setConfig(_txtColor:UIColor,_lineColor:UIColor,_txtFont:UIFont,_iconLeft:CGFloat) {
335 | txtColor = _txtColor
336 | txtFont = _txtFont
337 | lineColor = _lineColor
338 | iconLeft = _iconLeft
339 |
340 | line.backgroundColor = lineColor
341 | lblTitle.textColor = txtColor
342 | lblTitle.font = txtFont
343 | }
344 |
345 | override func layoutSubviews() {
346 | super.layoutSubviews()
347 | print(self.bounds)
348 | self.iconImage.frame = CGRect(x: iconLeft, y: (self.bounds.size.height - 20)/2, width: 20, height: 20)
349 | self.lblTitle.frame = CGRect(x: 20+iconLeft*2, y: 0, width: self.bounds.size.width - 40, height: self.bounds.size.height)
350 | self.line.frame = CGRect(x: 0, y: self.frame.size.height - 1, width: self.frame.size.width, height: 1)
351 |
352 | }
353 |
354 |
355 | }
356 |
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | FA12F7871DF18166002F5FE1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA12F7861DF18166002F5FE1 /* AppDelegate.swift */; };
11 | FA12F7891DF18166002F5FE1 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA12F7881DF18166002F5FE1 /* ViewController.swift */; };
12 | FA12F78C1DF18166002F5FE1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA12F78A1DF18166002F5FE1 /* Main.storyboard */; };
13 | FA12F78E1DF18166002F5FE1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA12F78D1DF18166002F5FE1 /* Assets.xcassets */; };
14 | FA12F7911DF18166002F5FE1 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA12F78F1DF18166002F5FE1 /* LaunchScreen.storyboard */; };
15 | FA12F79C1DF18166002F5FE1 /* SwiftPopMenuUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA12F79B1DF18166002F5FE1 /* SwiftPopMenuUITests.swift */; };
16 | FA12F7AA1DF27AC3002F5FE1 /* SwiftPopMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA12F7A91DF27AC3002F5FE1 /* SwiftPopMenu.swift */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXContainerItemProxy section */
20 | FA12F7981DF18166002F5FE1 /* PBXContainerItemProxy */ = {
21 | isa = PBXContainerItemProxy;
22 | containerPortal = FA12F77B1DF18166002F5FE1 /* Project object */;
23 | proxyType = 1;
24 | remoteGlobalIDString = FA12F7821DF18166002F5FE1;
25 | remoteInfo = SwiftPopMenu;
26 | };
27 | /* End PBXContainerItemProxy section */
28 |
29 | /* Begin PBXFileReference section */
30 | FA12F7831DF18166002F5FE1 /* SwiftPopMenu.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SwiftPopMenu.app; sourceTree = BUILT_PRODUCTS_DIR; };
31 | FA12F7861DF18166002F5FE1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
32 | FA12F7881DF18166002F5FE1 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
33 | FA12F78B1DF18166002F5FE1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
34 | FA12F78D1DF18166002F5FE1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
35 | FA12F7901DF18166002F5FE1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
36 | FA12F7921DF18166002F5FE1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
37 | FA12F7971DF18166002F5FE1 /* SwiftPopMenuUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SwiftPopMenuUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
38 | FA12F79B1DF18166002F5FE1 /* SwiftPopMenuUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftPopMenuUITests.swift; sourceTree = ""; };
39 | FA12F79D1DF18166002F5FE1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
40 | FA12F7A91DF27AC3002F5FE1 /* SwiftPopMenu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftPopMenu.swift; sourceTree = ""; };
41 | /* End PBXFileReference section */
42 |
43 | /* Begin PBXFrameworksBuildPhase section */
44 | FA12F7801DF18166002F5FE1 /* Frameworks */ = {
45 | isa = PBXFrameworksBuildPhase;
46 | buildActionMask = 2147483647;
47 | files = (
48 | );
49 | runOnlyForDeploymentPostprocessing = 0;
50 | };
51 | FA12F7941DF18166002F5FE1 /* Frameworks */ = {
52 | isa = PBXFrameworksBuildPhase;
53 | buildActionMask = 2147483647;
54 | files = (
55 | );
56 | runOnlyForDeploymentPostprocessing = 0;
57 | };
58 | /* End PBXFrameworksBuildPhase section */
59 |
60 | /* Begin PBXGroup section */
61 | FA12F77A1DF18166002F5FE1 = {
62 | isa = PBXGroup;
63 | children = (
64 | FA12F7851DF18166002F5FE1 /* SwiftPopMenu */,
65 | FA12F79A1DF18166002F5FE1 /* SwiftPopMenuUITests */,
66 | FA12F7841DF18166002F5FE1 /* Products */,
67 | );
68 | sourceTree = "";
69 | };
70 | FA12F7841DF18166002F5FE1 /* Products */ = {
71 | isa = PBXGroup;
72 | children = (
73 | FA12F7831DF18166002F5FE1 /* SwiftPopMenu.app */,
74 | FA12F7971DF18166002F5FE1 /* SwiftPopMenuUITests.xctest */,
75 | );
76 | name = Products;
77 | sourceTree = "";
78 | };
79 | FA12F7851DF18166002F5FE1 /* SwiftPopMenu */ = {
80 | isa = PBXGroup;
81 | children = (
82 | FA12F7A81DF27AC3002F5FE1 /* SwiftPopMenuSrc */,
83 | FA12F7861DF18166002F5FE1 /* AppDelegate.swift */,
84 | FA12F7881DF18166002F5FE1 /* ViewController.swift */,
85 | FA12F78A1DF18166002F5FE1 /* Main.storyboard */,
86 | FA12F78D1DF18166002F5FE1 /* Assets.xcassets */,
87 | FA12F78F1DF18166002F5FE1 /* LaunchScreen.storyboard */,
88 | FA12F7921DF18166002F5FE1 /* Info.plist */,
89 | );
90 | path = SwiftPopMenu;
91 | sourceTree = "";
92 | };
93 | FA12F79A1DF18166002F5FE1 /* SwiftPopMenuUITests */ = {
94 | isa = PBXGroup;
95 | children = (
96 | FA12F79B1DF18166002F5FE1 /* SwiftPopMenuUITests.swift */,
97 | FA12F79D1DF18166002F5FE1 /* Info.plist */,
98 | );
99 | path = SwiftPopMenuUITests;
100 | sourceTree = "";
101 | };
102 | FA12F7A81DF27AC3002F5FE1 /* SwiftPopMenuSrc */ = {
103 | isa = PBXGroup;
104 | children = (
105 | FA12F7A91DF27AC3002F5FE1 /* SwiftPopMenu.swift */,
106 | );
107 | path = SwiftPopMenuSrc;
108 | sourceTree = "";
109 | };
110 | /* End PBXGroup section */
111 |
112 | /* Begin PBXNativeTarget section */
113 | FA12F7821DF18166002F5FE1 /* SwiftPopMenu */ = {
114 | isa = PBXNativeTarget;
115 | buildConfigurationList = FA12F7A01DF18166002F5FE1 /* Build configuration list for PBXNativeTarget "SwiftPopMenu" */;
116 | buildPhases = (
117 | FA12F77F1DF18166002F5FE1 /* Sources */,
118 | FA12F7801DF18166002F5FE1 /* Frameworks */,
119 | FA12F7811DF18166002F5FE1 /* Resources */,
120 | );
121 | buildRules = (
122 | );
123 | dependencies = (
124 | );
125 | name = SwiftPopMenu;
126 | productName = SwiftPopMenu;
127 | productReference = FA12F7831DF18166002F5FE1 /* SwiftPopMenu.app */;
128 | productType = "com.apple.product-type.application";
129 | };
130 | FA12F7961DF18166002F5FE1 /* SwiftPopMenuUITests */ = {
131 | isa = PBXNativeTarget;
132 | buildConfigurationList = FA12F7A31DF18166002F5FE1 /* Build configuration list for PBXNativeTarget "SwiftPopMenuUITests" */;
133 | buildPhases = (
134 | FA12F7931DF18166002F5FE1 /* Sources */,
135 | FA12F7941DF18166002F5FE1 /* Frameworks */,
136 | FA12F7951DF18166002F5FE1 /* Resources */,
137 | );
138 | buildRules = (
139 | );
140 | dependencies = (
141 | FA12F7991DF18166002F5FE1 /* PBXTargetDependency */,
142 | );
143 | name = SwiftPopMenuUITests;
144 | productName = SwiftPopMenuUITests;
145 | productReference = FA12F7971DF18166002F5FE1 /* SwiftPopMenuUITests.xctest */;
146 | productType = "com.apple.product-type.bundle.ui-testing";
147 | };
148 | /* End PBXNativeTarget section */
149 |
150 | /* Begin PBXProject section */
151 | FA12F77B1DF18166002F5FE1 /* Project object */ = {
152 | isa = PBXProject;
153 | attributes = {
154 | LastSwiftUpdateCheck = 0810;
155 | LastUpgradeCheck = 0810;
156 | ORGANIZATIONNAME = zyyj;
157 | TargetAttributes = {
158 | FA12F7821DF18166002F5FE1 = {
159 | CreatedOnToolsVersion = 8.1;
160 | ProvisioningStyle = Automatic;
161 | };
162 | FA12F7961DF18166002F5FE1 = {
163 | CreatedOnToolsVersion = 8.1;
164 | ProvisioningStyle = Automatic;
165 | TestTargetID = FA12F7821DF18166002F5FE1;
166 | };
167 | };
168 | };
169 | buildConfigurationList = FA12F77E1DF18166002F5FE1 /* Build configuration list for PBXProject "SwiftPopMenu" */;
170 | compatibilityVersion = "Xcode 3.2";
171 | developmentRegion = English;
172 | hasScannedForEncodings = 0;
173 | knownRegions = (
174 | English,
175 | en,
176 | Base,
177 | );
178 | mainGroup = FA12F77A1DF18166002F5FE1;
179 | productRefGroup = FA12F7841DF18166002F5FE1 /* Products */;
180 | projectDirPath = "";
181 | projectRoot = "";
182 | targets = (
183 | FA12F7821DF18166002F5FE1 /* SwiftPopMenu */,
184 | FA12F7961DF18166002F5FE1 /* SwiftPopMenuUITests */,
185 | );
186 | };
187 | /* End PBXProject section */
188 |
189 | /* Begin PBXResourcesBuildPhase section */
190 | FA12F7811DF18166002F5FE1 /* Resources */ = {
191 | isa = PBXResourcesBuildPhase;
192 | buildActionMask = 2147483647;
193 | files = (
194 | FA12F7911DF18166002F5FE1 /* LaunchScreen.storyboard in Resources */,
195 | FA12F78E1DF18166002F5FE1 /* Assets.xcassets in Resources */,
196 | FA12F78C1DF18166002F5FE1 /* Main.storyboard in Resources */,
197 | );
198 | runOnlyForDeploymentPostprocessing = 0;
199 | };
200 | FA12F7951DF18166002F5FE1 /* Resources */ = {
201 | isa = PBXResourcesBuildPhase;
202 | buildActionMask = 2147483647;
203 | files = (
204 | );
205 | runOnlyForDeploymentPostprocessing = 0;
206 | };
207 | /* End PBXResourcesBuildPhase section */
208 |
209 | /* Begin PBXSourcesBuildPhase section */
210 | FA12F77F1DF18166002F5FE1 /* Sources */ = {
211 | isa = PBXSourcesBuildPhase;
212 | buildActionMask = 2147483647;
213 | files = (
214 | FA12F7891DF18166002F5FE1 /* ViewController.swift in Sources */,
215 | FA12F7AA1DF27AC3002F5FE1 /* SwiftPopMenu.swift in Sources */,
216 | FA12F7871DF18166002F5FE1 /* AppDelegate.swift in Sources */,
217 | );
218 | runOnlyForDeploymentPostprocessing = 0;
219 | };
220 | FA12F7931DF18166002F5FE1 /* Sources */ = {
221 | isa = PBXSourcesBuildPhase;
222 | buildActionMask = 2147483647;
223 | files = (
224 | FA12F79C1DF18166002F5FE1 /* SwiftPopMenuUITests.swift in Sources */,
225 | );
226 | runOnlyForDeploymentPostprocessing = 0;
227 | };
228 | /* End PBXSourcesBuildPhase section */
229 |
230 | /* Begin PBXTargetDependency section */
231 | FA12F7991DF18166002F5FE1 /* PBXTargetDependency */ = {
232 | isa = PBXTargetDependency;
233 | target = FA12F7821DF18166002F5FE1 /* SwiftPopMenu */;
234 | targetProxy = FA12F7981DF18166002F5FE1 /* PBXContainerItemProxy */;
235 | };
236 | /* End PBXTargetDependency section */
237 |
238 | /* Begin PBXVariantGroup section */
239 | FA12F78A1DF18166002F5FE1 /* Main.storyboard */ = {
240 | isa = PBXVariantGroup;
241 | children = (
242 | FA12F78B1DF18166002F5FE1 /* Base */,
243 | );
244 | name = Main.storyboard;
245 | sourceTree = "";
246 | };
247 | FA12F78F1DF18166002F5FE1 /* LaunchScreen.storyboard */ = {
248 | isa = PBXVariantGroup;
249 | children = (
250 | FA12F7901DF18166002F5FE1 /* Base */,
251 | );
252 | name = LaunchScreen.storyboard;
253 | sourceTree = "";
254 | };
255 | /* End PBXVariantGroup section */
256 |
257 | /* Begin XCBuildConfiguration section */
258 | FA12F79E1DF18166002F5FE1 /* Debug */ = {
259 | isa = XCBuildConfiguration;
260 | buildSettings = {
261 | ALWAYS_SEARCH_USER_PATHS = NO;
262 | CLANG_ANALYZER_NONNULL = YES;
263 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
264 | CLANG_CXX_LIBRARY = "libc++";
265 | CLANG_ENABLE_MODULES = YES;
266 | CLANG_ENABLE_OBJC_ARC = YES;
267 | CLANG_WARN_BOOL_CONVERSION = YES;
268 | CLANG_WARN_CONSTANT_CONVERSION = YES;
269 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
270 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
271 | CLANG_WARN_EMPTY_BODY = YES;
272 | CLANG_WARN_ENUM_CONVERSION = YES;
273 | CLANG_WARN_INFINITE_RECURSION = YES;
274 | CLANG_WARN_INT_CONVERSION = YES;
275 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
276 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
277 | CLANG_WARN_UNREACHABLE_CODE = YES;
278 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
279 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
280 | COPY_PHASE_STRIP = NO;
281 | DEBUG_INFORMATION_FORMAT = dwarf;
282 | ENABLE_STRICT_OBJC_MSGSEND = YES;
283 | ENABLE_TESTABILITY = YES;
284 | GCC_C_LANGUAGE_STANDARD = gnu99;
285 | GCC_DYNAMIC_NO_PIC = NO;
286 | GCC_NO_COMMON_BLOCKS = YES;
287 | GCC_OPTIMIZATION_LEVEL = 0;
288 | GCC_PREPROCESSOR_DEFINITIONS = (
289 | "DEBUG=1",
290 | "$(inherited)",
291 | );
292 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
293 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
294 | GCC_WARN_UNDECLARED_SELECTOR = YES;
295 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
296 | GCC_WARN_UNUSED_FUNCTION = YES;
297 | GCC_WARN_UNUSED_VARIABLE = YES;
298 | IPHONEOS_DEPLOYMENT_TARGET = 10.1;
299 | MTL_ENABLE_DEBUG_INFO = YES;
300 | ONLY_ACTIVE_ARCH = YES;
301 | SDKROOT = iphoneos;
302 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
303 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
304 | SWIFT_VERSION = 5.0;
305 | };
306 | name = Debug;
307 | };
308 | FA12F79F1DF18166002F5FE1 /* Release */ = {
309 | isa = XCBuildConfiguration;
310 | buildSettings = {
311 | ALWAYS_SEARCH_USER_PATHS = NO;
312 | CLANG_ANALYZER_NONNULL = YES;
313 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
314 | CLANG_CXX_LIBRARY = "libc++";
315 | CLANG_ENABLE_MODULES = YES;
316 | CLANG_ENABLE_OBJC_ARC = YES;
317 | CLANG_WARN_BOOL_CONVERSION = YES;
318 | CLANG_WARN_CONSTANT_CONVERSION = YES;
319 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
320 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
321 | CLANG_WARN_EMPTY_BODY = YES;
322 | CLANG_WARN_ENUM_CONVERSION = YES;
323 | CLANG_WARN_INFINITE_RECURSION = YES;
324 | CLANG_WARN_INT_CONVERSION = YES;
325 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
326 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
327 | CLANG_WARN_UNREACHABLE_CODE = YES;
328 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
329 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
330 | COPY_PHASE_STRIP = NO;
331 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
332 | ENABLE_NS_ASSERTIONS = NO;
333 | ENABLE_STRICT_OBJC_MSGSEND = YES;
334 | GCC_C_LANGUAGE_STANDARD = gnu99;
335 | GCC_NO_COMMON_BLOCKS = YES;
336 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
337 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
338 | GCC_WARN_UNDECLARED_SELECTOR = YES;
339 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
340 | GCC_WARN_UNUSED_FUNCTION = YES;
341 | GCC_WARN_UNUSED_VARIABLE = YES;
342 | IPHONEOS_DEPLOYMENT_TARGET = 10.1;
343 | MTL_ENABLE_DEBUG_INFO = NO;
344 | SDKROOT = iphoneos;
345 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
346 | SWIFT_VERSION = 5.0;
347 | VALIDATE_PRODUCT = YES;
348 | };
349 | name = Release;
350 | };
351 | FA12F7A11DF18166002F5FE1 /* Debug */ = {
352 | isa = XCBuildConfiguration;
353 | buildSettings = {
354 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
355 | INFOPLIST_FILE = SwiftPopMenu/Info.plist;
356 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
357 | PRODUCT_BUNDLE_IDENTIFIER = www.zyyj.com.cn.SwiftPopMenu;
358 | PRODUCT_NAME = "$(TARGET_NAME)";
359 | SWIFT_VERSION = 5.0;
360 | };
361 | name = Debug;
362 | };
363 | FA12F7A21DF18166002F5FE1 /* Release */ = {
364 | isa = XCBuildConfiguration;
365 | buildSettings = {
366 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
367 | INFOPLIST_FILE = SwiftPopMenu/Info.plist;
368 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
369 | PRODUCT_BUNDLE_IDENTIFIER = www.zyyj.com.cn.SwiftPopMenu;
370 | PRODUCT_NAME = "$(TARGET_NAME)";
371 | SWIFT_VERSION = 5.0;
372 | };
373 | name = Release;
374 | };
375 | FA12F7A41DF18166002F5FE1 /* Debug */ = {
376 | isa = XCBuildConfiguration;
377 | buildSettings = {
378 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
379 | INFOPLIST_FILE = SwiftPopMenuUITests/Info.plist;
380 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
381 | PRODUCT_BUNDLE_IDENTIFIER = www.zyyj.com.cn.SwiftPopMenuUITests;
382 | PRODUCT_NAME = "$(TARGET_NAME)";
383 | SWIFT_VERSION = 5.0;
384 | TEST_TARGET_NAME = SwiftPopMenu;
385 | };
386 | name = Debug;
387 | };
388 | FA12F7A51DF18166002F5FE1 /* Release */ = {
389 | isa = XCBuildConfiguration;
390 | buildSettings = {
391 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
392 | INFOPLIST_FILE = SwiftPopMenuUITests/Info.plist;
393 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
394 | PRODUCT_BUNDLE_IDENTIFIER = www.zyyj.com.cn.SwiftPopMenuUITests;
395 | PRODUCT_NAME = "$(TARGET_NAME)";
396 | SWIFT_VERSION = 5.0;
397 | TEST_TARGET_NAME = SwiftPopMenu;
398 | };
399 | name = Release;
400 | };
401 | /* End XCBuildConfiguration section */
402 |
403 | /* Begin XCConfigurationList section */
404 | FA12F77E1DF18166002F5FE1 /* Build configuration list for PBXProject "SwiftPopMenu" */ = {
405 | isa = XCConfigurationList;
406 | buildConfigurations = (
407 | FA12F79E1DF18166002F5FE1 /* Debug */,
408 | FA12F79F1DF18166002F5FE1 /* Release */,
409 | );
410 | defaultConfigurationIsVisible = 0;
411 | defaultConfigurationName = Release;
412 | };
413 | FA12F7A01DF18166002F5FE1 /* Build configuration list for PBXNativeTarget "SwiftPopMenu" */ = {
414 | isa = XCConfigurationList;
415 | buildConfigurations = (
416 | FA12F7A11DF18166002F5FE1 /* Debug */,
417 | FA12F7A21DF18166002F5FE1 /* Release */,
418 | );
419 | defaultConfigurationIsVisible = 0;
420 | defaultConfigurationName = Release;
421 | };
422 | FA12F7A31DF18166002F5FE1 /* Build configuration list for PBXNativeTarget "SwiftPopMenuUITests" */ = {
423 | isa = XCConfigurationList;
424 | buildConfigurations = (
425 | FA12F7A41DF18166002F5FE1 /* Debug */,
426 | FA12F7A51DF18166002F5FE1 /* Release */,
427 | );
428 | defaultConfigurationIsVisible = 0;
429 | defaultConfigurationName = Release;
430 | };
431 | /* End XCConfigurationList section */
432 | };
433 | rootObject = FA12F77B1DF18166002F5FE1 /* Project object */;
434 | }
435 |
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu.xcodeproj/project.xcworkspace/xcuserdata/MACBOOK.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TangledHusky/SwiftPopMenu/cba2bf540b52ee9c0cc13b6ea639cd102f1ebbf1/SwiftPopMenuDemo/SwiftPopMenu.xcodeproj/project.xcworkspace/xcuserdata/MACBOOK.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu.xcodeproj/project.xcworkspace/xcuserdata/liyajun.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TangledHusky/SwiftPopMenu/cba2bf540b52ee9c0cc13b6ea639cd102f1ebbf1/SwiftPopMenuDemo/SwiftPopMenu.xcodeproj/project.xcworkspace/xcuserdata/liyajun.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu.xcodeproj/xcuserdata/MACBOOK.xcuserdatad/xcschemes/SwiftPopMenu.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
66 |
72 |
73 |
74 |
75 |
76 |
77 |
83 |
85 |
91 |
92 |
93 |
94 |
96 |
97 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu.xcodeproj/xcuserdata/MACBOOK.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SwiftPopMenu.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | FA12F7821DF18166002F5FE1
16 |
17 | primary
18 |
19 |
20 | FA12F7961DF18166002F5FE1
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu.xcodeproj/xcuserdata/liyajun.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu.xcodeproj/xcuserdata/liyajun.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SwiftPopMenu.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SwiftPopMenu
4 | //
5 | // Created by lyj on 2016/12/2.
6 | // Copyright © 2016年 zyyj. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | }
43 | ],
44 | "info" : {
45 | "version" : 1,
46 | "author" : "xcode"
47 | }
48 | }
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/Shape.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Shape.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "Shape@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "Shape@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/Shape.imageset/Shape.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TangledHusky/SwiftPopMenu/cba2bf540b52ee9c0cc13b6ea639cd102f1ebbf1/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/Shape.imageset/Shape.png
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/Shape.imageset/Shape@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TangledHusky/SwiftPopMenu/cba2bf540b52ee9c0cc13b6ea639cd102f1ebbf1/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/Shape.imageset/Shape@2x.png
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/Shape.imageset/Shape@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TangledHusky/SwiftPopMenu/cba2bf540b52ee9c0cc13b6ea639cd102f1ebbf1/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/Shape.imageset/Shape@3x.png
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/SignRule.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "SignRule.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "SignRule@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "SignRule@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/SignRule.imageset/SignRule.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TangledHusky/SwiftPopMenu/cba2bf540b52ee9c0cc13b6ea639cd102f1ebbf1/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/SignRule.imageset/SignRule.png
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/SignRule.imageset/SignRule@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TangledHusky/SwiftPopMenu/cba2bf540b52ee9c0cc13b6ea639cd102f1ebbf1/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/SignRule.imageset/SignRule@2x.png
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/SignRule.imageset/SignRule@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TangledHusky/SwiftPopMenu/cba2bf540b52ee9c0cc13b6ea639cd102f1ebbf1/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/SignRule.imageset/SignRule@3x.png
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/saoyisao.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "saoyisao.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "saoyisao@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "saoyisao@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/saoyisao.imageset/saoyisao.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TangledHusky/SwiftPopMenu/cba2bf540b52ee9c0cc13b6ea639cd102f1ebbf1/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/saoyisao.imageset/saoyisao.png
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/saoyisao.imageset/saoyisao@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TangledHusky/SwiftPopMenu/cba2bf540b52ee9c0cc13b6ea639cd102f1ebbf1/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/saoyisao.imageset/saoyisao@2x.png
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/saoyisao.imageset/saoyisao@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TangledHusky/SwiftPopMenu/cba2bf540b52ee9c0cc13b6ea639cd102f1ebbf1/SwiftPopMenuDemo/SwiftPopMenu/Assets.xcassets/saoyisao.imageset/saoyisao@3x.png
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu/SwiftPopMenuSrc/SwiftPopMenu.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PopView.swift
3 | // TestSwift
4 | //
5 | // Created by lyj on 16/5/7.
6 | // Copyright © 2016年 zyyj. All rights reserved.
7 | /*
8 | GitHub:https://github.com/TangledHusky/SwiftPopMenu
9 |
10 | 功能:
11 | 只需要传入菜单箭头点位置、菜单宽度、数据源即可。
12 |
13 | 1、支持任意点弹出(点是基于整个屏幕位置)
14 | 2、会根据点位置自动计算菜单位置
15 | 3、背景色、文字等支持自定义设置
16 | 4、菜单最大宽度=屏幕-边距 最大高度=屏幕高度一半
17 | */
18 |
19 | import UIKit
20 |
21 | protocol SwiftPopMenuDelegate :NSObjectProtocol{
22 | func swiftPopMenuDidSelectIndex(index:Int)
23 | }
24 |
25 |
26 | public enum SwiftPopMenuConfigure {
27 | case PopMenuTextFont(UIFont) //菜单文字字体
28 | case PopMenuTextColor(UIColor) //菜单文字颜色
29 | case PopMenuBackgroudColor(UIColor) //菜单背景色
30 | case popMenuCornorRadius(CGFloat) //菜单圆角
31 | case popMenuItemHeight(CGFloat) //菜单行高度
32 | case popMenuSplitLineColor(UIColor) //菜单分割线颜色
33 | case popMenuIconLeftMargin(CGFloat) //icon左间距
34 | case popMenuMargin(CGFloat) //菜单与屏幕边距
35 | case popMenuAlpha(CGFloat) //菜单背景透明度
36 | }
37 |
38 | public class SwiftPopMenu: UIView {
39 |
40 | //delegate
41 | weak var delegate : SwiftPopMenuDelegate?
42 | //block
43 | public var didSelectMenuBlock:((_ index:Int)->Void)?
44 |
45 | let KScrW:CGFloat = UIScreen.main.bounds.size.width
46 | let KScrH:CGFloat = UIScreen.main.bounds.size.height
47 |
48 |
49 |
50 | ///* ----------------------- 外部参数 通过configure设置 ---------------------------- */
51 | //区域外背景透明度
52 | private var popMenuOutAlpha:CGFloat = 0.3
53 | //背景色
54 | private var popMenuBgColor:UIColor = UIColor.white
55 | //圆角弧度
56 | private var popMenuCornorRadius:CGFloat = 6
57 | //文字颜色
58 | private var popMenuTextColor:UIColor = UIColor.black
59 | //字体大小等
60 | private var popMenuTextFont:UIFont = UIFont.systemFont(ofSize: 17)
61 | //菜单高度
62 | private var popMenuItemHeight:CGFloat = 44.0
63 | //菜单分割线颜色
64 | private var popMenuSplitLineColor:UIColor = UIColor(red: 222/255.0, green: 222/255.0, blue: 222/255.0, alpha: 0.5)
65 | //icon左间距
66 | private var popMenuIconLeftMargin:CGFloat = 15
67 | //菜单与屏幕边距
68 | private var popMenuMargin:CGFloat = 10
69 |
70 | ///* ----------------------- 外部参数 over------------------------------------------ */
71 |
72 | private var arrowPoint : CGPoint = CGPoint.zero //小箭头位置
73 | private var arrowViewWidth : CGFloat = 15 //三角箭头宽
74 | private var arrowViewHeight : CGFloat = 10 //三角箭头高
75 | private var popData:[(icon:String,title:String)]! //数据源
76 |
77 | static let cellID:String = "SwiftPopMenuCellID"
78 | private var myFrame:CGRect! //tableview frame
79 | private var arrowView : UIView! = nil
80 |
81 | var tableView:UITableView! = nil
82 |
83 |
84 |
85 | /// 初始化菜单
86 | ///
87 | /// - Parameters:
88 | /// - menuWidth: 菜单宽度
89 | /// - arrow: 箭头位置是popmenu相对整个屏幕的位置
90 | /// - datas: 数据源,icon允许传空,数据源没数据,不会显示菜单
91 | /// - configure: 配置信息,可不传
92 | init(menuWidth:CGFloat,arrow:CGPoint,datas:[(icon:String,title:String)],configures:[SwiftPopMenuConfigure] = []) {
93 | super.init(frame: UIScreen.main.bounds)
94 | self.frame = UIScreen.main.bounds
95 | //读取配置
96 | configures.forEach { (config) in
97 | switch (config){
98 | case let .PopMenuTextFont(value):
99 | popMenuTextFont = value
100 | case let .PopMenuTextColor(value):
101 | popMenuTextColor = value
102 | case let .PopMenuBackgroudColor(value):
103 | popMenuBgColor = value
104 | case let .popMenuCornorRadius(value):
105 | popMenuCornorRadius = value
106 | case let .popMenuItemHeight(value):
107 | popMenuItemHeight = value
108 | case let .popMenuSplitLineColor(value):
109 | popMenuSplitLineColor = value
110 | case let .popMenuIconLeftMargin(value):
111 | popMenuIconLeftMargin = value
112 | case let .popMenuMargin(value):
113 | popMenuMargin = value
114 | case let .popMenuAlpha(value):
115 | popMenuOutAlpha = value
116 | }
117 | }
118 |
119 | popData = datas
120 | //设置myFrame size ,original会在后面计算
121 | myFrame = CGRect(x: 0, y: 0, width: menuWidth, height: popMenuItemHeight*CGFloat(popData.count))
122 | myFrame.size.height = min(KScrH/2, myFrame.height)
123 | myFrame.size.width = min(KScrW-popMenuMargin*2, myFrame.width)
124 |
125 | //设置肩头,与屏幕间隔10
126 | arrowPoint = arrow
127 | arrowPoint.x = max(popMenuMargin, min(arrowPoint.x, KScrW-popMenuMargin))
128 |
129 | }
130 |
131 | required public init?(coder aDecoder: NSCoder) {
132 | fatalError("init(coder:) has not been implemented")
133 | }
134 |
135 |
136 |
137 | func initViews() {
138 | self.backgroundColor = UIColor.black.withAlphaComponent(popMenuOutAlpha)
139 |
140 | let arrowPs = getArrowPoints()
141 | myFrame.origin = arrowPs.3
142 | let isarrowUP = arrowPs.4
143 | print(arrowPs)
144 | //箭头
145 | arrowView=UIView(frame: CGRect(x: myFrame.origin.x, y: isarrowUP ? myFrame.origin.y-arrowViewHeight : myFrame.origin.y+myFrame.height, width: myFrame.width, height: arrowViewHeight))
146 | let layer=CAShapeLayer()
147 | let path=UIBezierPath()
148 | path.move(to: arrowPs.0)
149 | path.addLine(to: arrowPs.1)
150 | path.addLine(to: arrowPs.2)
151 | layer.path=path.cgPath
152 | layer.fillColor = popMenuBgColor.cgColor
153 | arrowView.layer.addSublayer(layer)
154 | self.addSubview(arrowView)
155 |
156 | tableView=UITableView(frame: CGRect(x: myFrame.origin.x,y: myFrame.origin.y,width: myFrame.width,height: myFrame.height), style: .plain)
157 | tableView.register(SwiftPopMenuCell.classForCoder(), forCellReuseIdentifier: SwiftPopMenu.cellID)
158 | tableView.backgroundColor = popMenuBgColor
159 | tableView.layer.cornerRadius = popMenuCornorRadius
160 | tableView.separatorStyle = .none
161 | tableView.layer.masksToBounds = true
162 | tableView.delegate = self
163 | tableView.dataSource = self
164 | tableView.bounces = false
165 | UIView.animate(withDuration: 0.3) {
166 | self.addSubview(self.tableView)
167 | }
168 | }
169 |
170 |
171 | /// 计算箭头位置
172 | ///
173 | /// - Returns: (三角箭头顶,三角箭头左,三角箭头右,tableview 原点,是否箭头朝上)
174 | func getArrowPoints() -> (CGPoint,CGPoint,CGPoint,CGPoint,Bool) {
175 | if arrowPoint.x <= popMenuMargin {
176 | arrowPoint.x = popMenuMargin
177 | }
178 | if arrowPoint.x >= KScrW - popMenuMargin{
179 | arrowPoint.x = KScrW - popMenuMargin
180 | }
181 | var originalPoint = CGPoint.zero
182 |
183 | //箭头中间距离左边距离
184 | var arrowMargin:CGFloat = popMenuMargin
185 | if arrowPoint.x < KScrW/2{
186 | if (arrowPoint.x > myFrame.width/2) {
187 | arrowMargin = myFrame.width/2
188 | originalPoint = CGPoint(x: arrowPoint.x - myFrame.width/2, y: arrowPoint.y+arrowViewHeight)
189 | }else{
190 | arrowMargin = arrowPoint.x-popMenuMargin
191 | originalPoint = CGPoint(x: popMenuMargin, y: arrowPoint.y+arrowViewHeight)
192 | }
193 |
194 | }else{
195 |
196 | if (KScrW-arrowPoint.x) < myFrame.width/2{
197 | arrowMargin = (myFrame.width - KScrW + arrowPoint.x )
198 | originalPoint = CGPoint(x: KScrW-popMenuMargin-myFrame.width, y: arrowPoint.y+arrowViewHeight)
199 |
200 |
201 | }else{
202 | arrowMargin = myFrame.width/2
203 | originalPoint = CGPoint(x: arrowPoint.x-myFrame.width/2, y: arrowPoint.y+arrowViewHeight)
204 | }
205 | }
206 |
207 | //箭头朝上
208 | if (KScrH - arrowPoint.y) > myFrame.height{
209 |
210 | return (CGPoint(x: arrowMargin, y: 0),CGPoint(x: arrowMargin-arrowViewWidth/2, y: arrowViewHeight),CGPoint(x: arrowMargin+arrowViewWidth/2, y: arrowViewHeight),originalPoint,true)
211 |
212 | }else{
213 | originalPoint.y = arrowPoint.y-myFrame.height-arrowViewHeight
214 |
215 | return (CGPoint(x: arrowMargin, y: arrowViewHeight),CGPoint(x: arrowMargin-arrowViewWidth/2, y: 0),CGPoint(x: arrowMargin+arrowViewWidth/2, y: 0),originalPoint,false)
216 | }
217 |
218 | }
219 |
220 | }
221 |
222 |
223 |
224 | // MARK: - 页面显示、隐藏
225 | extension SwiftPopMenu{
226 |
227 | override public func touchesBegan(_ touches: Set, with event: UIEvent?) {
228 | if touches.first?.view != tableView{
229 | dismiss()
230 | }
231 | }
232 |
233 | public func show() {
234 | if popData.isEmpty{
235 | return
236 | }
237 | initViews()
238 | UIApplication.shared.keyWindow?.addSubview(self)
239 | }
240 |
241 | public func dismiss() {
242 | self.removeFromSuperview()
243 | }
244 |
245 | }
246 |
247 | // MARK: - UITableViewDataSource,UITableViewDelegate
248 | extension SwiftPopMenu : UITableViewDataSource,UITableViewDelegate{
249 |
250 | public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
251 | return popData.count
252 | }
253 |
254 | public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
255 | if popData.count>indexPath.row {
256 | let cell = tableView.dequeueReusableCell(withIdentifier: SwiftPopMenu.cellID) as! SwiftPopMenuCell
257 |
258 | let model = popData[indexPath.row]
259 | cell.setConfig(_txtColor: popMenuTextColor, _lineColor: popMenuSplitLineColor, _txtFont: popMenuTextFont, _iconLeft: popMenuIconLeftMargin)
260 | if indexPath.row == popData.count - 1 {
261 | cell.fill(iconName: model.icon, title: model.title, islast: true)
262 | }else{
263 | cell.fill(iconName: model.icon, title: model.title)
264 | }
265 | return cell
266 | }
267 |
268 | return UITableViewCell()
269 | }
270 |
271 | public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
272 | return popMenuItemHeight
273 | }
274 |
275 | public func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
276 | return 0.01
277 | }
278 |
279 | public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
280 | if self.delegate != nil{
281 | self.delegate?.swiftPopMenuDidSelectIndex(index: indexPath.row)
282 | }
283 | if didSelectMenuBlock != nil {
284 | didSelectMenuBlock!(indexPath.row)
285 | }
286 |
287 | dismiss()
288 | }
289 |
290 | }
291 |
292 |
293 |
294 | /// UITableViewCell
295 | class SwiftPopMenuCell: UITableViewCell {
296 | var iconImage:UIImageView!
297 | var lblTitle:UILabel!
298 | var line:UIView!
299 |
300 | //自定义属性
301 | var lineColor:UIColor = UIColor(red: 222/255.0, green: 222/255.0, blue: 222/255.0, alpha: 0.5)
302 | var txtColor:UIColor = UIColor.black
303 | var txtFont:UIFont = UIFont.systemFont(ofSize: 17)
304 | var iconLeft:CGFloat = 15
305 |
306 |
307 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
308 | super.init(style: style, reuseIdentifier: reuseIdentifier)
309 | self.backgroundColor = UIColor.clear
310 |
311 | iconImage = UIImageView()
312 | self.contentView.addSubview(iconImage)
313 | self.selectionStyle = .none
314 |
315 | lblTitle = UILabel()
316 | self.contentView.addSubview(lblTitle)
317 |
318 | line = UIView()
319 | self.contentView.addSubview(line)
320 | }
321 |
322 |
323 | required init?(coder aDecoder: NSCoder) {
324 | fatalError("init(coder:) has not been implemented")
325 | }
326 |
327 |
328 | func fill(iconName:String,title:String,islast:Bool = false) {
329 | iconImage.image = UIImage(named: iconName)
330 | lblTitle.text = title
331 | line.isHidden = islast
332 | }
333 |
334 | func setConfig(_txtColor:UIColor,_lineColor:UIColor,_txtFont:UIFont,_iconLeft:CGFloat) {
335 | txtColor = _txtColor
336 | txtFont = _txtFont
337 | lineColor = _lineColor
338 | iconLeft = _iconLeft
339 |
340 | line.backgroundColor = lineColor
341 | lblTitle.textColor = txtColor
342 | lblTitle.font = txtFont
343 | }
344 |
345 | override func layoutSubviews() {
346 | super.layoutSubviews()
347 | self.iconImage.frame = CGRect(x: iconLeft, y: (self.bounds.size.height - 20)/2, width: 20, height: 20)
348 | self.lblTitle.frame = CGRect(x: 20+iconLeft*2, y: 0, width: self.bounds.size.width - 40, height: self.bounds.size.height)
349 | self.line.frame = CGRect(x: 0, y: self.frame.size.height - 1, width: self.frame.size.width, height: 1)
350 |
351 | }
352 |
353 |
354 | }
355 |
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenu/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // SwiftPopMenu
4 | //
5 | // Created by lyj on 2016/12/2.
6 | // Copyright © 2016年 zyyj. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | var popMenu:SwiftPopMenu!
14 |
15 | let KSCREEN_WIDTH:CGFloat = UIScreen.main.bounds.size.width
16 | let KSCREEN_HEIGHT:CGFloat = UIScreen.main.bounds.size.height
17 |
18 | lazy var btn:UIButton = {
19 | let btn = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 40))
20 | btn.center = self.view.center
21 | btn.backgroundColor = UIColor.black
22 | btn.setTitle("点击测试", for: .normal)
23 | btn.addTarget(self, action: #selector(showMenu), for: .touchUpInside)
24 | return btn
25 | }()
26 |
27 | override func viewDidLoad() {
28 | super.viewDidLoad()
29 | view.addSubview(btn)
30 | self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(named: "Shape"), style: .plain, target: self, action: #selector(self.showMenu))
31 | }
32 |
33 | @objc func showMenu() {
34 | //数据源(icon可不填)
35 | let popData = [(icon:"saoyisao",title:"扫一扫"),
36 | (icon:"SignRule",title:"签到规则"),
37 | (icon:"saoyisao",title:"扫一扫"),
38 | (icon:"SignRule",title:"签到规则")]
39 |
40 | //设置参数
41 | let parameters:[SwiftPopMenuConfigure] = [
42 | .PopMenuTextColor(UIColor.black),
43 | .popMenuItemHeight(44),
44 | .PopMenuTextFont(UIFont.systemFont(ofSize: 18))
45 | ]
46 |
47 |
48 | //init (test随机生成点位置,注意:arrow点是基于屏幕的位置)
49 | popMenu = SwiftPopMenu(menuWidth: 150, arrow: CGPoint(x: btn.center.x, y: btn.center.y+30), datas: popData,configures: parameters)
50 |
51 | //click
52 | popMenu.didSelectMenuBlock = { [weak self](index:Int)->Void in
53 | print("block select \(index)")
54 | self?.popMenu = nil
55 | }
56 | //show
57 | popMenu.show()
58 |
59 | }
60 |
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenuUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/SwiftPopMenuDemo/SwiftPopMenuUITests/SwiftPopMenuUITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SwiftPopMenuUITests.swift
3 | // SwiftPopMenuUITests
4 | //
5 | // Created by 李亚军 on 2016/12/2.
6 | // Copyright © 2016年 zyyj. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class SwiftPopMenuUITests: XCTestCase {
12 |
13 | override func setUp() {
14 | super.setUp()
15 |
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 |
18 | // In UI tests it is usually best to stop immediately when a failure occurs.
19 | continueAfterFailure = false
20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
21 | XCUIApplication().launch()
22 |
23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
24 | }
25 |
26 | override func tearDown() {
27 | // Put teardown code here. This method is called after the invocation of each test method in the class.
28 | super.tearDown()
29 | }
30 |
31 | func testExample() {
32 | // Use recording to get started writing UI tests.
33 | // Use XCTAssert and related functions to verify your tests produce the correct results.
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/img1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TangledHusky/SwiftPopMenu/cba2bf540b52ee9c0cc13b6ea639cd102f1ebbf1/img1.png
--------------------------------------------------------------------------------
/img2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TangledHusky/SwiftPopMenu/cba2bf540b52ee9c0cc13b6ea639cd102f1ebbf1/img2.png
--------------------------------------------------------------------------------
/img3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TangledHusky/SwiftPopMenu/cba2bf540b52ee9c0cc13b6ea639cd102f1ebbf1/img3.png
--------------------------------------------------------------------------------
/swiftPopMenu.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TangledHusky/SwiftPopMenu/cba2bf540b52ee9c0cc13b6ea639cd102f1ebbf1/swiftPopMenu.gif
--------------------------------------------------------------------------------