ios官方菜单项目重点剖析附项目源码

原版教程:https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/index.html

项目知识重点:

1,使用堆栈视图实现自动布局。

2,自定义控件的创建与使用。

3,调用手机系统图片库。

开发环境:工具:Xcode8.2测试版,语言:swift3.0.1(由于环境原因,流程略微不同)

一,项目功能介绍及预览

主体功能:对一个菜单列表进行展示,删除,修改,添加操作

界面预览:

二,自定义控件

我们创建工程后先将我们的新增页面构建好,从预览图中可以看出是由一个导航条,文本框,和一个图片视图,还有五颗星构成。相信前几个控件都没什么问题,关键在于这个自定义控件。

我们都知道每一个控件都是会默认关联一个类的,所以:我们这个五角星评价控件(下文称rating)如出一辙的需要关联一个自定义的类。

 1 //
 2 //  RatingControl.swift
 3 //  Food
 4 //
 5 //  Created by C02 on 2016/12/14.
 6 //  Copyright © 2016年 Aida. All rights reserved.
 7 //
 8 
 9 import UIKit
10 
11 /*
12  自定义星级评价控件
13  */
14 class RatingControl: UIView {
15     
16     let spacing = 5//星星间距
17     let ratingCount = 5//星星个数
18     var filledArr = [UIButton]()//filled星星数组
19     var rating = 0 {
20         didSet{
21             setNeedsLayout()
22         }
23     }
24     
25     required init?(coder aDecoder: NSCoder) {
26         super.init(coder: aDecoder)
27         
28         for _ in 0..<ratingCount{
29             let btn = UIButton()
30             btn.setImage(UIImage(named:"empty"), for: .normal)
31             btn.setImage(UIImage(named: "filled"), for: .selected)
32             btn.setImage(UIImage(named: "filled"), for: [.highlighted,.selected])
33             btn.adjustsImageWhenHighlighted = false
34             //控件单击事件
35             btn.addTarget(self, action: #selector(RatingControl.ratingClicked(sender:)), for:.touchDown)
36             filledArr += [btn]
37             self.addSubview(btn)
38         }
39     }
40     
41     func ratingClicked(sender:UIButton){
42         rating = filledArr.index(of: sender)! + 1
43         updateBtnStar()
44     }
45     
46     func updateBtnStar(){
47         for(index,btn) in filledArr.enumerated(){
48             btn.isSelected = index < rating
49         }
50     }
51     
52     override func layoutSubviews() {
53         let size = Int(self.frame.height)
54         for (index,btn) in filledArr.enumerated() {
55             btn.frame = CGRect(x: index * (size + spacing), y: 0,  size, height: size)
56         }
57         updateBtnStar()
58     }
59     
60     //返回此控件大小
61     override var intrinsicContentSize: CGSize {
62         //控件默认高度44
63         let ratingHeight = Int(self.frame.height)
64         //控件宽度=星星数*(控件高度+间距)
65         let ratingWidth = ratingCount*(ratingHeight+spacing)
66         return CGSize( ratingWidth, height: ratingHeight)
67     }
68     
69 }
View Code

三,使用自定义控件

解析:在我们的视图控制器中加入文本框和图片后,再添加一个view视图,然后将这个view关联我们上一步定义的RatingControl类。

此时运行模拟器,便可以看到我们的rating控件,大小与位置我们稍后再做调整。

四,使用堆栈视图实现自动布局。

我们都知道我们的应用可能会运行在不同分辨率,不同尺寸,横屏,竖屏等状态下,所以布局自然不能一成不变。

1,选中三个控件->Xcode工具栏Editor->Embed In->StakeView将其嵌入到堆栈视图中,或者使用视图下方的快捷工具。

 2,添加合适的约束

我们要将我们的控件在各种情况下都可以得到正常的显示,可以将整个视图分割成若干个子视图,把子视图位置调整好。同理,一种层层处理方式再继续调整每一个控件。

显而易见,本例中我们先需要将栈调整。

选中StackView首先对上左右三个方向进行约束,但是此时并不能确定StackView的高度,在确定StackView中每一个控件的高度后,自然这个栈的所有约束也就完成了。

注意:在我们的ImageView和Rating控件需要固定大小需要如此设置

为了有良好的交互性,因此我们这里设置了一个默认的图片,以及控件之间的间距。

五,调用手机系统图库及配置手势操作

在新增项的时候我们需要通过点击视图中的默认图片添加一个手机图库中的图片。

注意:此时我们需要拖入一个UITapGestureRecognizer控件在ImageView上,要让点击有效此时必须启用用户交互,如图所示。

接下来就是将这个控件关联到我们的代码中

 1 //
 2 //  ViewController.swift
 3 //  Food
 4 //
 5 //  Created by Aida on 2016/12/14.
 6 //  Copyright © 2016年 Aida. All rights reserved.
 7 //
 8 
 9 import UIKit
10 
11 class ViewController: UIViewController ,UITextFieldDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate{
12 
13     @IBOutlet weak var nameText: UITextField!
14     
15     @IBOutlet weak var photoImg: UIImageView!
16     
17     @IBOutlet weak var ratingControl: RatingControl!
18     @IBOutlet weak var saveOutlet: UIBarButtonItem!
19     
20     var meal:Meal?
21     override func viewDidLoad() {
22         super.viewDidLoad()
23         self.nameText.delegate = self
24         
25         
26     }
27     
28     override func didReceiveMemoryWarning() {
29         super.didReceiveMemoryWarning()
30         // Dispose of any resources that can be recreated.
31     }
32 
33     //MARK: 手势识别方法
34     @IBAction func selectPhoto(_ sender: UITapGestureRecognizer) {
35         let imagePickerController = UIImagePickerController()
36         
37         imagePickerController.sourceType = .photoLibrary
38         
39         imagePickerController.delegate = self
40         
41         present(imagePickerController, animated: true, completion: nil)
42     }
43     
44     //图片选择之前取消事件
45     func imagePickerControllerDidCancel(_ picker: UIImagePickerController){
46         
47         dismiss(animated: true, completion: nil)
48     }
49     
50     //选中图片事件
51     func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]){
52         
53         let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage
54         
55         // Set photoImageView to display the selected image.
56         photoImg.image = selectedImage
57         
58         // Dismiss the picker.
59         dismiss(animated: true, completion: nil)
60     }
View Code

用户授权:由于应用要使用手机图库需要经过授权,因此需要在项目的info.plist文件中配置相关字段。

<key>Privacy - Photo Library Usage Description</key><string>您允许我们访问相册吗</string>

小结:到这一步,这个小项目的几个重点就介绍完了。有任何问题可以联系:QQ:1016882435.

另附项目完整源码:https://pan.baidu.com/s/1boDcwgB 密码:acsy

原文地址:https://www.cnblogs.com/1016882435AIDA/p/6171471.html