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

项目知识重点:

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

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

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

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

一,项目功能介绍及预览

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

界面预览:

二,自定义控件

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

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

 //
// RatingControl.swift
// Food
//
// Created by C02 on 2016/12/14.
// Copyright © 2016年 Aida. All rights reserved.
// import UIKit /*
自定义星级评价控件
*/
class RatingControl: UIView { let spacing = //星星间距
let ratingCount = //星星个数
var filledArr = [UIButton]()//filled星星数组
var rating = {
didSet{
setNeedsLayout()
}
} required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder) for _ in ..<ratingCount{
let btn = UIButton()
btn.setImage(UIImage(named:"empty"), for: .normal)
btn.setImage(UIImage(named: "filled"), for: .selected)
btn.setImage(UIImage(named: "filled"), for: [.highlighted,.selected])
btn.adjustsImageWhenHighlighted = false
//控件单击事件
btn.addTarget(self, action: #selector(RatingControl.ratingClicked(sender:)), for:.touchDown)
filledArr += [btn]
self.addSubview(btn)
}
} func ratingClicked(sender:UIButton){
rating = filledArr.index(of: sender)! +
updateBtnStar()
} func updateBtnStar(){
for(index,btn) in filledArr.enumerated(){
btn.isSelected = index < rating
}
} override func layoutSubviews() {
let size = Int(self.frame.height)
for (index,btn) in filledArr.enumerated() {
btn.frame = CGRect(x: index * (size + spacing), y: , width: size, height: size)
}
updateBtnStar()
} //返回此控件大小
override var intrinsicContentSize: CGSize {
//控件默认高度44
let ratingHeight = Int(self.frame.height)
//控件宽度=星星数*(控件高度+间距)
let ratingWidth = ratingCount*(ratingHeight+spacing)
return CGSize(width: ratingWidth, height: ratingHeight)
} }

三,使用自定义控件

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

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

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

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

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

2,添加合适的约束

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

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

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

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

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

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

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

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

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

 //
// ViewController.swift
// Food
//
// Created by Aida on 2016/12/14.
// Copyright © 2016年 Aida. All rights reserved.
// import UIKit class ViewController: UIViewController ,UITextFieldDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate{ @IBOutlet weak var nameText: UITextField! @IBOutlet weak var photoImg: UIImageView! @IBOutlet weak var ratingControl: RatingControl!
@IBOutlet weak var saveOutlet: UIBarButtonItem! var meal:Meal?
override func viewDidLoad() {
super.viewDidLoad()
self.nameText.delegate = self } override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
} //MARK: 手势识别方法
@IBAction func selectPhoto(_ sender: UITapGestureRecognizer) {
let imagePickerController = UIImagePickerController() imagePickerController.sourceType = .photoLibrary imagePickerController.delegate = self present(imagePickerController, animated: true, completion: nil)
} //图片选择之前取消事件
func imagePickerControllerDidCancel(_ picker: UIImagePickerController){ dismiss(animated: true, completion: nil)
} //选中图片事件
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]){ let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage // Set photoImageView to display the selected image.
photoImg.image = selectedImage // Dismiss the picker.
dismiss(animated: true, completion: nil)
}

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

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

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

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

ios官方菜单项目重点剖析附项目源码的更多相关文章

  1. Spring3 + Spring MVC+ Mybatis 3+Mysql 项目整合(注解及源码)

    Spring3 + Spring MVC+ Mybatis 3+Mysql 项目整合(注解及源码) 备注: 之前在Spring3 + Spring MVC+ Mybatis 3+Mysql 项目整合中 ...

  2. winserver的consul部署实践与.net core客户端使用(附demo源码)

    winserver的consul部署实践与.net core客户端使用(附demo源码)   前言 随着微服务兴起,服务的管理显得极其重要.都知道微服务就是”拆“,把臃肿的单块应用,拆分成多个轻量级的 ...

  3. 基于tomcat插件的maven多模块工程热部署(附插件源码)

    内容属原创,转载请注明出处 写在前面的话 最近一直比较纠结,归根结底在于工程的模块化拆分.以前也干过这事,但是一直对以前的结果不满意,这会重操旧业,希望搞出个自己满意的结果. 之前有什么不满意的呢? ...

  4. 嗨,让我带你逐行剖析Vue.js源码

    本项目受到了阮一峰老师的肯定,已刊登在阮一峰老师微信公众号的科技爱好者周刊第87期,同时也被多个微博大V转发,短短一个月时间内在github上star数量就已经突破2k! Hello,大家好,我最近在 ...

  5. Spring Boot整合ElasticSearch和Mysql 附案例源码

    导读 前二天,写了一篇ElasticSearch7.8.1从入门到精通的(点我直达),但是还没有整合到SpringBoot中,下面演示将ElasticSearch和mysql整合到Spring Boo ...

  6. 转:【Java集合源码剖析】HashMap源码剖析

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/36034955   您好,我正在参加CSDN博文大赛,如果您喜欢我的文章,希望您能帮我投一票 ...

  7. 【Java集合源码剖析】HashMap源码剖析

    转载出处:http://blog.csdn.net/ns_code/article/details/36034955 HashMap简介 HashMap是基于哈希表实现的,每一个元素是一个key-va ...

  8. 单独编译和使用webrtc音频回声消除模块(附完整源码+测试音频文件)

    单独编译和使用webrtc音频降噪模块(附完整源码+测试音频文件) 单独编译和使用webrtc音频增益模块(附完整源码+测试音频文件) 说实话很不想写这篇文章,因为这和我一贯推崇的最好全部编译并使用w ...

  9. 在WebBrowser中执行javascript脚本的几种方法整理(execScript/InvokeScript/NavigateScript) 附完整源码

    [实例简介] 涵盖了几种常用的 webBrowser执行javascript的方法,详见示例截图以及代码 [实例截图] [核心代码] execScript方式: 1 2 3 4 5 6 7 8 9 1 ...

随机推荐

  1. 批处理bat 命令

    1.批处理常用符号: - echo 打开回显或关闭请求回显功能,或显示消息.如果没有任何参数,echo 命令将显示当前回显设置 语法:@echo [{ on|off }]  echo{"显示 ...

  2. SQL Server 2012 新特性:其他

    安装期间的设置   为了强化角色分离,不自动在 sysadmin 固定服务器角色中设置 BUILTIN\administrators 和 Local System (NT AUTHORITY\SYST ...

  3. $(window).height(),在火狐下面获取的高度并不是可视区域的高度

    很简单,我发现是没有写<!DOCTYPE html>造成的,加上去就可以了

  4. WPF SpreadSheetGear电子表单

    我们经常会碰到生成Excel 界面并在其上操作的功能开发. 比如如下界面,我们需要在菜单里添加一个菜单按钮"Columns To Rows Transform" 功能是对多列批量转 ...

  5. find your present (感叹一下位运算的神奇)

    find your present (2) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  6. Linux的一些基本概述以及系统使用

    GNU:项目名称(意指开发在类UNIX系统上的软件).POSIX:可移植(Portable)操作系统接口,便于程序在不同操作系统上运行. Linux是符合POSIX标准的操作系统: 完全兼容POSIX ...

  7. Java开发的几个注意点

    原文出处: 后端技术杂谈 1. 将一些需要变动的配置写在属性文件中 比如,没有把一些需要并发执行时使用的线程数设置成可在属性文件中配置.那么你的程序无论在DEV环境中,还是TEST环境中,都可以顺畅无 ...

  8. mysql max_allowed_packet 设置过小导致记录写入失败

    mysql根据配置文件会限制server接受的数据包大小. 有时候大的插入和更新会受max_allowed_packet 参数限制,导致写入或者更新失败. 查看目前配置 show VARIABLES ...

  9. [LeetCode] Strong Password Checker 密码强度检查器

    A password is considered strong if below conditions are all met: It has at least 6 characters and at ...

  10. [LeetCode] Arithmetic Slices 算数切片

    A sequence of number is called arithmetic if it consists of at least three elements and if the diffe ...