上一篇开始用Swift开发iOS 10 - 11 面向对象编程介绍对代码做了一点修改,这一篇来丰富一下详情页和定制化Navigation Bar。
重新设计详细页面
选中
Main.storyboard
,删除Image View和三个Label。-
添加Table View,修改其大小为整个View,并且添加一些约束。设置
prototype cells
为1;table view cell的identifier
为Cell,row height
为36。
-
在table view的头部添加一个image view,给变其高度为300,宽度为View的宽度。
连接image view和
RestaurantDetailViewController
中的restaurantImageView
接口。修改Image View的
content mode
为 Aspect Fit,并勾选Clip to Bounds
定制 Prototype Cell
- 增加两个label,分别命名为Field,Value ,字体修改成自己想要的。把它们组成一个Stack View。
-
为Stack View添加一些约束。
在cell中垂直居中;Trailing Space 和 Leading Space都为零。
用Ctrl-drag从FieldLabel到ValueLabel,选择Equal Widths,生成一个FieldLabel与ValueLabel宽度相同的约束。修改Multiplier值为0.5,就是FieldLabel的宽度是ValueLabel的一半。
- 新建
RestaurantDetailTableViewCell
类文件,继承至UITableViewCell
。添加两个接口,并关联上面的两个Label。
@IBOutlet var fieldLabel:UILabel!
@IBOutlet var valueLabel:UILabel!
更新 RestaurantDetailViewController
实现
UITableViewDataSource
和UITableViewDelegate
:
class RestaurantDetailViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {实现
UITableViewDataSource
的相关方法:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! RestaurantDetailTableViewCell
// Configure the cell...
switch indexPath.row {
case 0:
cell.fieldLabel.text = "Name"
cell.valueLabel.text = restaurant.name
case 1:
cell.fieldLabel.text = "Type"
cell.valueLabel.text = restaurant.type
case 2:
cell.fieldLabel.text = "Location"
cell.valueLabel.text = restaurant.location
case 3:
cell.fieldLabel.text = "Been here"
cell.valueLabel.text = (restaurant.isVisited) ? "Yes, I've been herebefore" : "No"
default:
cell.fieldLabel.text = ""
cell.valueLabel.text = ""
}
cell.backgroundColor = UIColor.clear
return cell
}
- 把table view的
delegate
和dataSource
接口设置成Restaurant Detail View Controller 。
定制table view 的样式
在
RestaurantDetailViewController
中添加一个接口变量,并关联storyboard中的table view。
@IBOutlet var tableView:UITableView!
-
设置table view的背景颜色,在
viewDidLoad
中添加:
tableView.backgroundColor = UIColor(red: 240.0/255.0, green: 240.0/255.0, blue: 240.0/255.0, alpha: 0.2)
新加的颜色是亮灰色(和白色相近,可以设置成其他深颜色做对比),运行后不是整个table view都变色。
这是因为,每一个cell都是重新添加的,cell的背景颜色还是默认的白色,覆盖了table view的背景颜色,要在tableView(_:cellForRowAt:)
的return
之前添加:
cell.backgroundColor = UIColor.clear
移除table view中空cell的分割线,在
viewDidLoad
中添加:
tableView.tableFooterView = UIView(frame: CGRect.zero)改变分割线的颜色, 在
viewDidLoad
中添加:
tableView.separatorColor = UIColor(red: 240.0/255.0, green: 240.0/255.0, blue: 240.0/255.0, alpha: 0.8)
定制Navigation Bar的样式
通过UINavigationBar.appearance()
修改Navigation Bar的样式。
Navigation Bar的样式修改是整体修改的,所以修改Navigation Bar的样式代码要写在application(_:didFinishLaunchingWithOptions:)
方法中。
- 修改navigation bar的背景颜色:
UINavigationBar.appearance().barTintColor = UIColor(red: 216.0/255.0, green: 74.0/255.0, blue: 32.0/255.0, alpha: 1.0) - 修改title样式:
if let barFont = UIFont(name: "Avenir-Light", size: 24.0) {
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName:UIColor.white, NSFontAttributeName:barFont]
}
Avenir-Light
是字体名称,详细的iOS字体可查 http://iosfonts.com 。
-
tintColor
控制Navigation items和bar button items的颜色
UINavigationBar.appearance().tintColor = UIColor.white
目前,Navigation bar的返回按钮是一个<
和Food Pin
,想删除Food Pin
,需要修改RestaurantTableViewController
的backBarButtonItem
属性。
在 RestaurantTableViewController
的viewDidLoad
中添加:
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
为 detail view 的 Navigation bar 添加title,在 RestaurantDetailViewController
的viewDidLoad
中添加:
title = restaurant.name
隐藏Navigation Bar
- 自从iOS 8后,Navigation Bar可以在不同情况下隐藏,在storyboard中选择Navigation Controller修改。(
On Swipe
是向上滑)
但这种设置整个app的Navigation Bar都会隐藏。如果只想在restaurant table view controller中隐藏,在detail view中不隐藏,就需要在两个控制器的
viewDidLoad
分别设置:navigationController?.hidesBarsOnSwipe = true
和navigationController?.hidesBarsOnSwipe = false
。-
运行反复测试后发现两个问题:
- 当从detail view返回后,restaurant table view controller的 Navigation Bar不能隐藏。
- 当restaurant table view controller的 Navigation Bar隐藏后进入detail view后, Navigation Bar消失不能再显示。
首先明确两个控制器中的navigationController
属性指的是同一个Navigation Controller ,viewDidLoad
方法是view第一次加载时调用,之后就不再调用了。 也就是说当从detail view返回,hidesBarsOnSwipe
已经被设置为false
,而到restaurant table view controller的viewDidLoad
不再调用,所以Navigation Bar不能再隐藏。
解决办法是使用viewWillAppear
,这个方法是在视图每一次显示时调用。
在RestaurantTableViewController
中添加:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.hidesBarsOnSwipe = true
}
在RestaurantDetailViewController
中添加:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
navigationController?.hidesBarsOnSwipe = false
navigationController?.setNavigationBarHidden(false, animated: true)
}
修改Status Bar样式
app中Status Bar的默认样式是黑色。
在Info.plist
中添加一个key为View controller-based status bar appearance,值为NO。然后application(_:didFinishLaunchingWithOptions:)
中添加:UIApplication.shared.statusBarStyle = .lightContent
。
代码
Beginning-iOS-Programming-with-Swift
说明
此文是学习appcode网站出的一本书 《Beginning iOS 10 Programming with Swift》 的一篇记录
系列文章目录
- 开始用Swift开发iOS 10 - 1 前言
- 开始用Swift开发iOS 10 - 2 Hello World!第一个Swift APP
- 开始用Swift开发iOS 10 - 3 介绍Auto Layout
- 开始用Swift开发iOS 10 - 4 用Stack View设计UI
- [开始用Swift开发iOS 10 - 5 原型的介绍]
- 开始用Swift开发iOS 10 - 6 创建简单的Table Based App
- 开始用Swift开发iOS 10 - 7 定制Table Views
- 开始用Swift开发iOS 10 - 8 Table View和UIAlertController的交互
- 开始用Swift开发iOS 10 - 9 Table Row的删除, UITableViewRowAction和UIActivityViewController的使用
- 开始用Swift开发iOS 10 - 10 Navigation Controller的介绍和Segue
- 开始用Swift开发iOS 10 - 11 面向对象编程介绍