如何在iOS 8中使用Swift和xcode5 ios8 6制作精美的UI组件

ios8 - UIPopoverController, Xcode 6, IOS 8 using Swift - Stack Overflow
Join Stack Overflow to learn, share knowledge, and build your career.
or sign in with
I'm having some trouble getting a UIPopover to appear using swift.
The code that is commented out works fine in Objective-C, but doesn't work using Swift. When I tap the + in my view controller I do get the "click" in my debugger, however no popover appears.
class PlayerInformationTableViewController: UITableViewController, NSFetchedResultsControllerDelegate, UIPopoverControllerDelegate {
@IBOutlet weak var addBarButtonItem: UIBarButtonItem!
var playerInformationViewController = PlayerInformationViewController()
var popover:UIPopoverController?
override func viewDidLoad() {
super.viewDidLoad()
//setup the popover
_cuesPopoverViewController
= [self.storyboard instantiateViewControllerWithIdentifier:@"CuesPopoverViewController"];
self.cuesPopover
= [[UIPopoverController alloc] initWithContentViewController:_cuesPopoverViewController];
self.cuesPopover.popoverContentSize = CGSizeMake(540, 300);
self.cuesPopover.delegate
playerInformationViewController.storyboard?.instantiateViewControllerWithIdentifier("PlayerInformationViewController")
popover?.contentViewController = playerInformationViewController
popover?.popoverContentSize = CGSizeMake(300, 300)
popover?.delegate = self
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
@IBAction func addPopover(sender: AnyObject) {
println("Click")
popover?.presentPopoverFromBarButtonItem(addBarButtonItem, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)
override func viewDidLoad() {
super.viewDidLoad()
@IBAction func addPopover(sender: AnyObject) {
var popoverViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PlayerInformationViewController") as UIViewController
popoverViewController.modalPresentationStyle = .Popover
popoverViewController.preferredContentSize
= CGSizeMake(450, 450)
let popoverPresentationViewController = popoverViewController.popoverPresentationController
popoverPresentationViewController?.permittedArrowDirections = .Any
popoverPresentationViewController?.delegate = self
popoverPresentationViewController?.barButtonItem = sender as UIBarButtonItem
presentViewController(popoverViewController, animated: true, completion: nil)
Here is a simple example for iOS 8. Popover are presented using adaptivity apis in iOS 8.
class PlayerInformationTableViewController: UITableViewController, UIPopoverPresentationControllerDelegate, NSFetchedResultsControllerDelegate{
@IBAction func addPopover(sender: UIBarButtonItem){
let playerInformationViewController =
PlayerInformationViewController()
playerInformationViewController.modalPresentationStyle = .Popover
playerInformationViewController.preferredContentSize = CGSizeMake(300, 300)
let popoverPresentationViewController = playerInformationViewController.popoverPresentationController
popoverPresentationViewController?.permittedArrowDirections = .Any
popoverPresentationViewController?.delegate = self
popoverPresentationController?.barButtonItem = sender
presentViewController(playerInformationViewController, animated: true, completion: nil)
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController!) -& UIModalPresentationStyle{
return .None
11.7k44081
Display Popover with contentView from xib
func showPopover(sender: AnyObject) {
let contentViewController = UINib(nibName: "ContentVC", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as ContentVC
contentViewController.modalPresentationStyle = UIModalPresentationStyle.Popover
var detailPopover: UIPopoverPresentationController = contentViewController.popoverPresentationController!
detailPopover.delegate = self
detailPopover.barButtonItem = sender as UIBarButtonItem
detailPopover.permittedArrowDirections = UIPopoverArrowDirection.Any
presentViewController(contentViewController,
animated: true, completion:nil)
Next allows to make not full screen PopoverView on iPhone
for this do not forget to inherit MainViewController: UIPopoverPresentationControllerDelegate
and set delegate to PopoverView
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController!) -& UIModalPresentationStyle
return .None
6,262145795
1,21811524
It looks like your popover is nil. Where are you assigning/instantiating it?
Try changing this:
popover?.presentPopoverFromBarButtonItem(addBarButtonItem, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)
if let pop = popover {
pop.presentPopoverFromBarButtonItem(addBarButtonItem, permittedArrowDirections: UIPopoverArrowDirection.Any, animated: true)
NSLog("Error: Popover was nil")
I imagine you'll see that error message in your console. In the .XIB for your PlayerInformationTableViewController, do you have a UIPopoverController?
If so, you probably need to ensure that the var popover is either (1) being manually instantiated in your awakeFromNib, or that it's an @IBOutlet and is being connected properly.
Alternatively, can you simply use the popover already present in your playerInformationViewController?
16k1787164
Your Answer
Sign up or
Sign up using Google
Sign up using Facebook
Post as a guest
Post as a guest
By posting your answer, you agree to the
Not the answer you're looking for?
Browse other questions tagged
The week's top questions and answers
Important community announcements
Questions that need answers
By subscribing, you agree to the
Stack Overflow works best with JavaScript enabled如何在iOS 8中使用Swift和Xcode 6制作精美的UI组件
在Xcode6中加入了两个新的Interface Builder(下文用IB简称)属性声明:IBInspectable和IBDesignable。IBInspectable在IB的Attribute Inspector(属性检查器)中查看类的属性,而IBDesignable能实时更新视图,很厉害吧
译者:CocoaChina翻译小组成员dada(),欢迎加入我们的译者小组(,并注明社区ID、工作状态、电话以及个人博客等任何让我们更了解你的方式)
原文: (原文作者 ) &&
苹果在Xcode 6中加入了两个新的Interface Builder(下文用IB简称)属性声明:IBInspectable和IBDesignable。IBInspectable在IB的Attribute Inspector(属性检查器)中查看类的属性,而IBDesignable能实时更新视图,很厉害吧!
这里用一个简短的[(得爬墙哦!)说明下怎样使用IBInspectable和IBDesignable。10分钟就能看完所有的步骤。代码在[]
IBInspectable
以下是我发现的适用于IBInspectable的类型:
下面这些数据都对IBInspectable有效:
举个小栗子
class&OverCustomizableView&:&UIView&{&&&&&@IBInspectable&var&integer:&Int&=&0&&&&&@IBInspectable&var&float:&CGFloat&=&0&&&&&@IBInspectable&var&double:&Double&=&0&&&&&@IBInspectable&var&point:&CGPoint&=&CGPointZero&&&&&@IBInspectable&var&size:&CGSize&=&CGSizeZero&&&&&@IBInspectable&var&customFrame:&CGRect&=&CGRectZero&&&&&@IBInspectable&var&color:&UIColor&=&UIColor.clearColor()&&&&&@IBInspectable&var&string:&String&=&&We&?&Swift&&&&&&@IBInspectable&var&bool:&Bool&=&false&}&
在属性检查器的上面是这样:
这一切添加了一些用户定义的运行时属性,这些属性将会在view加载时设置它的初始值。
运行时属性的创建:
IBDesignable
来看个好玩的地方。IBDesignable告诉IB它可以加载并渲染视图。这个视图类必须在一个框架里面才能正常工作。不过这种方式也不会太麻烦,我们下面会看到方法。 我认为IB是隐式地将UIView的代码转换成NSView的代码,这样就能动态地加载框架并渲染组件。
创建新工程
打开Xcode6,创建一个新的&Single Page Application& (单页面应用)并选择Swift作为编程语言。
添加新的Target
在导航选中工程文件点击&+&按钮添加新的target
选择Framework & Application Library和choose the Cocoa Touch Framework,如图
命名为MyCustomView。Xcode会自动链接MyCustomView.framework到你的工程。
创建自定义视图类
创建一个新的swift文件,并添加到MyCustomView框架里。
右键单击框架的目录。
选择Cocoa Touch文件
给它命名为CustomView,作为UIView的子视图
CustomView.swift文件里包含:
import&UIKit&&class&CustomView:&UIView&{&&&&&&init(frame:&CGRect)&{&&&&&&&&&super.init(frame:&frame)&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&}&
移除生成的方法。
import&UIKit&&class&CustomView:&UIView&{&&}&
告诉Xcode用@IBDesignable 关键字来渲染你的视图。
添加三个属性:borderColor: UIColor, borderWidth: CGFloat以及cornerRadius: CGFloat。
设置默认值,并让它们是可检验的:
@IBDesignable&class&CustomView&:&UIView&{&&&&&@IBInspectable&var&borderColor:&UIColor&=&UIColor.clearColor()&&&&&&@IBInspectable&var&borderWidth:&CGFloat&=&0&&&&&&@IBInspectable&var&cornerRadius:&CGFloat&=&0&&}&
为视图层属性添加逻辑
为每个属性添加[property observers](观察者属性),并根据layer更新。
class&CustomView&:&UIView&{&&&&&@IBInspectable&var&borderColor:&UIColor&=&UIColor.clearColor()&{&&&&&&&&&didSet&{&&&&&&&&&&&&&layer.borderColor&=&borderColor.CGColor&&&&&&&&&}&&&&&}&&&&&&@IBInspectable&var&borderWidth:&CGFloat&=&0&{&&&&&&&&&didSet&{&&&&&&&&&&&&&layer.borderWidth&=&borderWidth&&&&&&&&&}&&&&&}&&&&&&@IBInspectable&var&cornerRadius:&CGFloat&=&0&{&&&&&&&&&didSet&{&&&&&&&&&&&&&layer.cornerRadius&=&cornerRadius&&&&&&&&&}&&&&&}&}&
按编译框架
测试自定义视图
打开Main.storyboard,从组件库里添加一个视图。
在Identity Inspector里把视图类改成CustomView。
调整视图,如果需要可添加自动布局约束。
Tip:按住选中视图并拖动鼠标到另一个视图可以添加自动布局约束。
上手玩了一下`cornerRadius`,我发现当添加一些比较大的值时会创建一个有意思的模式。
CocoaChina是全球最大的苹果开发中文社区,官方微信每日定时推送各种精彩的研发教程资源和工具,介绍app推广营销经验,最新企业招聘和外包信息,以及Cocos2d引擎、Cocos Studio开发工具包的最新动态及培训信息。关注微信可以第一时间了解最新产品和服务动态,微信在手,天下我有!
请搜索微信号“CocoaChina”关注我们!
关注微信 每日推荐
扫一扫 浏览移动版11432人阅读
Swift(4)
最近也想试水一下iOS应用开发,但又没有Apple Air/Pro之类的设备,也不想装OS X系统,就想到能不能在Windows或者ubuntu下安装XCode6环境来开发Swift?但经过一翻搜索,得到的答案是:XCode只能装在OS X系统上。据我了解目前Windows下是无法安装Swift编译运行环境的,有的文章为了吸引眼球,直接把标题写成“Windows下用xcode开发swift程序的图文教程”,打开一看,就是要安装虚拟机,安装MacOS系统的。如果你不是为了编写&iOS 和 OS X 应用,只是想学习了解一下Swift的语法,又或者用Swift写个服务,做Web后端开发的话(什么?Swift可以做Web后端开发?我没听错吧!没错,这是真的!将来Swift可以开发Android应用,或是Windows程序都有可能!),在Ubuntu下是没有问题的,参考:。另外在搜索过程中还了解到:Ubuntu下可以安装Object-C的编译环境,不过我没有试过行不行,有兴趣的可以参考:将来Swift或者可以开发Android应用,这不是我意淫,可以参考:Swift可以做Web后端开发,没错,这个我已经试过了,可以参考:只是我现在还没有发现比较好的框架可以用。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:9729978次
积分:68377
积分:68377
排名:第33名
原创:872篇
转载:242篇
译文:53篇
评论:1967条
文章:158篇
阅读:2633222
文章:33篇
阅读:232906
文章:18篇
阅读:204789
阅读:18200
文章:29篇
阅读:458626
文章:18篇
阅读:424559
文章:44篇
阅读:433192
(31)(34)(17)(11)(59)(30)(17)(14)(18)(27)(16)(9)(23)(20)(17)(4)(16)(12)(17)(25)(34)(19)(15)(17)(15)(23)(12)(12)(14)(13)(14)(20)(58)(25)(31)(16)(33)(31)(20)(24)(23)(21)(20)(14)(36)(14)(14)(7)(5)(15)(3)(2)(9)(6)(7)(32)(3)(8)(7)(22)(2)(30)(4)
关注我的订阅号“微wx笑”在iOS 8中使用UIAlertController
招聘信息:
iOS 8的新特性之一就是让接口更有适应性、更灵活,因此许多视图控制器的实现方式发生了巨大的变化。全新的UIPresentationController在实现视图控制器间的过渡动画效果和自适应设备尺寸变化效果(比如说旋转)中发挥了重要的作用,它有效地节省了程序员们的工作量(天地良心啊)。还有,某些旧的UIKit控件也同样发生了许多变化,比如说Alert Views、Action Sheets、Popovers以及Search Bar Controllers。本文将会对Alert Views和Action Sheets发生的改变进行一个大致的介绍,我们会采用Objective-C和swift两种语言同时进行代码说明。UIAlertView随着苹果上次iOS 5的发布,对话框视图样式出现在了我们面前,直到现在它都没有发生过很大的变化。下面的代码片段展示了如何初始化和显示一个带有“取消”和“好的”按钮的对话框视图。Objective-C版本:UIAlertView&*alertview&=&[[UIAlertView&alloc]&initWithTitle:@"标题"&message:@"这个是UIAlertView的默认样式"&delegate:self&cancelButtonTitle:@"取消"&otherButtonTitles:@"好的",&nil];
[alertview&show];UIAlertView的默认样式swift版本和Objective-C版本不同,在swift中,alertView的初始化只允许创建拥有一个取消按钮的对话框视图。或许您可以看到带有otherButtonTitles的init方法,但是很遗憾,这个方法是没有办法通过编译的。var&alertView&=&UIAlertView(title:&"标题",&message:&"这个是UIAlertView的默认样式",&delegate:&self,&cancelButtonTitle:&"取消")
alertView.show()swift版本的UIAlertView要能够创建和上面Objective-C版本相同的对话框视图,我们可以采取曲线救国的方法,虽然麻烦了些,但是我们为了目的可以不择手段的,是吧?var&alertView&=&UIAlertView()
alertView.delegate&=&self
alertView.title&=&"标题"
alertView.message&=&"这个是UIAlertView的默认样式"
alertView.addButtonWithTitle("取消")
alertView.addButtonWithTitle("好的")
alertView.show()您也可以通过更改UIAlertView的alertViewStyle属性来实现输入文字、密码甚至登录框的效果。UIAlertView文本对话框UIAlertView密码对话框UIAlertView登录对话框UIAlertViewDelegate协议拥有响应对话框视图的按钮动作的回调方法。还有当文本框内容改变时,调用alertViewShouldEnableOtherButton:方法可以让按钮动态地可用或者不可用。要说明一点,苹果官方现在并不提倡在iOS 8中使用UIAlertView,取而代之的是UIAlertController。下面我们就来介绍UIAlertController的使用方法。UIAlertController在iOS 8中,UIAlertController在功能上是和UIAlertView以及UIActionSheet相同的,UIAlertController以一种模块化替换的方式来代替这两货的功能和作用。是使用对话框(alert)还是使用上拉菜单(action sheet),就取决于在创建控制器时,您是如何设置首选样式的。一个简单的对话框例子您可以比较一下两种不同的创建对话框的代码,创建基础UIAlertController的代码和创建UIAlertView的代码非常相似:Objective-C版本:UIAlertController&*alertController&=&[UIAlertController&alertControllerWithTitle:@"标题"&message:@"这个是UIAlertController的默认样式"&preferredStyle:UIAlertControllerStyleAlert];swift版本:var&alertController&=&UIAlertController(title:&"标题",&message:&"这个是UIAlertController的默认样式",&preferredStyle:&UIAlertControllerStyle.Alert)同创建UIAlertView相比,我们无需指定代理,也无需在初始化过程中指定按钮。不过要特别注意第三个参数,要确定您选择的是对话框样式还是上拉菜单样式。通过创建UIAlertAction的实例,您可以将动作按钮添加到控制器上。UIAlertAction由标题字符串、样式以及当用户选中该动作时运行的代码块组成。通过UIAlertActionStyle,您可以选择如下三种动作样式:常规(default)、取消(cancel)以及警示(destruective)。为了实现原来我们在创建UIAlertView时创建的按钮效果,我们只需创建这两个动作按钮并将它们添加到控制器上即可。Objective-C版本:UIAlertAction&*cancelAction&=&[UIAlertAction&actionWithTitle:@"取消"&style:UIAlertActionStyleCancel&handler:nil];
UIAlertAction&*okAction&=&[UIAlertAction&actionWithTitle:@"好的"&style:UIAlertActionStyleDefault&handler:nil];
[alertController&addAction:cancelAction];
[alertController&addAction:okAction];swift版本:var&cancelAction&=&UIAlertAction(title:&"取消",&style:&UIAlertActionStyle.Cancel,&handler:&nil)
var&okAction&=&UIAlertAction(title:&"好的",&style:&UIAlertActionStyle.Default,&handler:&nil)
alertController.addAction(cancelAction)
alertController.addAction(okAction)最后,我们只需显示这个对话框视图控制器即可:Objective-C版本:[self&presentViewController:alertController&animated:YES&completion:nil];swift版本:self.presentViewController(alertController,&animated:&true,&completion:&nil)UIAlertController默认样式按钮显示的次序取决于它们添加到对话框控制器上的次序。一般来说,根据苹果官方制定的《iOS 用户界面指南》,在拥有两个按钮的对话框中,您应当将取消按钮放在左边。要注意,取消按钮是唯一的,如果您添加了第二个取消按钮,那么你就会得到如下的一个运行时异常:* Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘UIAlertController can only have one action with a style of UIAlertActionStyleCancel’异常信息简洁明了,我们在此就不赘述了。“警示”样式什么是“警示”样式呢?我们先不着急回答这个问题,先来看一下下面关于“警示”样式的简单示例。在这个示例中,我们将前面的示例中的“好的”按钮替换为了“重置”按钮。Objective-C版本:UIAlertAction&*resetAction&=&[UIAlertAction&actionWithTitle:@"重置"&style:UIAlertActionStyleDestructive&handler:nil];
[alertController&addAction:resetAction];swift版本:var&resetAction&=&UIAlertAction(title:&"重置",&style:&UIAlertActionStyle.Destructive,&handler:&nil)
alertController.addAction(resetAction)“警示”样式可以看出,我们新增的那个“重置”按钮变成了红色。根据苹果官方的定义,“警示”样式的按钮是用在可能会改变或删除数据的操作上。因此用了红色的醒目标识来警示用户。文本对话框UIAlertController极大的灵活性意味着您不必拘泥于内置样式。以前我们只能在默认视图、文本框视图、密码框视图、登录和密码输入框视图中选择,现在我们可以向对话框中添加任意数目的UITextField对象,并且可以使用所有的UITextField特性。当您向对话框控制器中添加文本框时,您需要指定一个用来配置文本框的代码块。举个栗子吧,要重新建立原来的登录和密码样式对话框,我们可以向其中添加两个文本框,然后用合适的占位符来配置它们,最后将密码输入框设置使用安全文本输入。Objective-C版本:UIAlertController&*alertController&=&[UIAlertController&alertControllerWithTitle:@"文本对话框"&message:@"登录和密码对话框示例"&preferredStyle:UIAlertControllerStyleAlert];
[alertController&addTextFieldWithConfigurationHandler:^(UITextField&*textField){
&&&&textField.placeholder&=&@"登录";
[alertController&addTextFieldWithConfigurationHandler:^(UITextField&*textField)&{
&&&&textField.placeholder&=&@"密码";
&&&&textField.secureTextEntry&=&YES;
}];swift版本:alertController.addTextFieldWithConfigurationHandler&{&
(textField:&UITextField!)&->&Void&in
&&&&textField.placeholder&=&"登录"
alertController.addTextFieldWithConfigurationHandler&{&
(textField:&UITextField!)&->&Void&in
&&&&textField.placeholder&=&"密码"
&&&&textField.secureTextEntry&=&true
}在“好的”按钮按下时,我们让程序读取文本框中的值。Objective-C版本:UIAlertAction&*okAction&=&[UIAlertAction&actionWithTitle:@"好的"&style:UIAlertActionStyleDefault&handler:^(UIAlertAction&*action)&{
&&&&UITextField&*login&=&alertController.textFields.firstO
&&&&UITextField&*password&=&alertController.textFields.lastO
}];swift版本:var&okAction&=&UIAlertAction(title:&"好的",&style:&UIAlertActionStyle.Default)&{
(action:&UIAlertAction!)&->&Void&in
&&&&var&login&=&alertController.textFields?.first&as&UITextField
&&&&var&password&=&alertController.textFields?.last&as&UITextField
}如果我们想要实现UIAlertView中的委托方法alertViewShouldEnableOtherButton:方法的话可能会有一些复杂。假定我们要让“登录”文本框中至少有3个字符才能激活“好的”按钮。很遗憾的是,在UIAlertController中并没有相应的委托方法,因此我们需要向“登录”文本框中添加一个Observer。Observer模式定义对象间的一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。我们可以在构造代码块中添加如下的代码片段来实现。Objective-C版本:[alertController&addTextFieldWithConfigurationHandler:^(UITextField&*textField){
&&&&[[NSNotificationCenter&defaultCenter]&addObserver:self&selector:@selector(alertTextFieldDidChange:)&name:UITextFieldTextDidChangeNotification&object:textField];
}];swift版本:alertController.addTextFieldWithConfigurationHandler&{
(textField:&UITextField!)&->&Void&in
&&&&NSNotificationCenter.defaultCenter().addObserver(self,&selector:&Selector("alertTextFieldDidChange:"),&name:&UITextFieldTextDidChangeNotification,&object:&textField)
}当视图控制器释放的时候我们需要移除这个Observer,我们通过在每个按钮动作的handler代码块(还有其他任何可能释放视图控制器的地方)中添加合适的代码来实现它。比如说在okAction这个按钮动作中:Objective-C版本:UIAlertAction&*okAction&=&[UIAlertAction&actionWithTitle:@"好的"&style:UIAlertActionStyleDefault&handler:^(UIAlertAction&*action)&{
&&&&[[NSNotificationCenter&defaultCenter]&removeObserver:self&name:UITextFieldTextDidChangeNotification&object:nil];
}];swift版本:var&okAction&=&UIAlertAction(title:&"好的",&style:&UIAlertActionStyle.Default)&{
(action:&UIAlertAction!)&->&Void&in
&&&&NSNotificationCenter.defaultCenter().removeObserver(self,&name:&UITextFieldTextDidChangeNotification,&object:&nil)
}在显示对话框之前,我们要冻结“好的”按钮Objective-C版本:okAction.enabled&=&NO;swift版本:okAction.enabled&=&false接下来,在通知观察者(notification observer)中,我们需要在激活按钮状态前检查“登录”文本框的内容。Objective-C版本:-&(void)alertTextFieldDidChange:(NSNotification&*)notification{
&&&&UIAlertController&*alertController&=&(UIAlertController&*)self.presentedViewC
&&&&if&(alertController)&{
&&&&&&&&UITextField&*login&=&alertController.textFields.firstO
&&&&&&&&UIAlertAction&*okAction&=&alertController.actions.lastO
&&&&&&&&okAction.enabled&=&login.text.length&>&2;
}swift版本:func&alertTextFieldDidChange(notification:&NSNotification){
&&&&var&alertController&=&self.presentedViewController&as&UIAlertController?
&&&&if&(alertController&!=&nil)&{
&&&&&&&&var&login&=&alertController!.textFields?.first&as&UITextField
&&&&&&&&var&okAction&=&alertController!.actions.last&as&UIAlertAction
&&&&&&&&okAction.enabled&=&countElements(login.text)&>&2
}UIAlertController的登录和密码对话框示例好了,现在对话框的“好的”按钮被冻结了,除非在“登录”文本框中输入3个以上的字符:上拉菜单当需要给用户展示一系列选择的时候(选择恐惧症患者杀手),上拉菜单就能够派上大用场了。和对话框不同,上拉菜单的展示形式和设备大小有关。在iPhone上(紧缩宽度),上拉菜单从屏幕底部升起。在iPad上(常规宽度),上拉菜单以弹出框的形式展现。创建上拉菜单的方式和创建对话框的方式非常类似,唯一的区别是它们的形式。Objective-C版本:UIAlertController&*alertController&=&[UIAlertController&alertControllerWithTitle:@"保存或删除数据"&message:@"删除数据将不可恢复"&preferredStyle:&UIAlertControllerStyleActionSheet];swift版本:var&alertController&=&UIAlertController(title:&"保存或删除数据",&message:&"删除数据将不可恢复",&preferredStyle:&UIAlertControllerStyle.ActionSheet)添加按钮动作的方式和对话框相同。Objective-C版本:UIAlertAction&*cancelAction&=&[UIAlertAction&actionWithTitle:@"取消"&style:UIAlertActionStyleCancel&handler:nil];
UIAlertAction&*deleteAction&=&[UIAlertAction&actionWithTitle:@"删除"&style:UIAlertActionStyleDestructive&handler:nil];
UIAlertAction&*archiveAction&=&[UIAlertAction&actionWithTitle:@"保存"&style:UIAlertActionStyleDefault&handler:nil];
[alertController&addAction:cancelAction];
[alertController&addAction:deleteAction];
[alertController&addAction:archiveAction];swift版本:var&cancelAction&=&UIAlertAction(title:&"取消",&style:&UIAlertActionStyle.Cancel,&handler:&nil)
var&deleteAction&=&UIAlertAction(title:&"删除",&style:&UIAlertActionStyle.Destructive,&handler:&nil)
var&archiveAction&=&UIAlertAction(title:&"保存",&style:&UIAlertActionStyle.Default,&handler:&nil)
alertController.addAction(cancelAction)
alertController.addAction(deleteAction)
alertController.addAction(archiveAction)您不能在上拉菜单中添加文本框,如果您强行作死添加了文本框,那么就会荣幸地得到一个运行时异常:* Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘Text fields can only be added to an alert controller of style UIAlertControllerStyleAlert’同样,简单的异常说明,我们也不多说了。接下来我们就可以在iPhone或者其他紧缩宽度的设备上展示了,不出我们所料,运行得很成功。Objective-C版本:[self&presentViewController:alertController&animated:YES&completion:nil];swift版本:self.presentViewController(alertController,&animated:&true,&completion:&nil)iPhone上的上拉菜单效果如果上拉菜单中有“取消”按钮的话,那么它永远都会出现在菜单的底部,不管添加的次序是如何(就是这么任性)。其他的按钮将会按照添加的次序从上往下依次显示。《iOS 用户界面指南》要求所有的“毁坏”样式按钮都必须排名第一(红榜嘛,很好理解的,对不对?)。别激动得太早,我们现在还有一个很严重的问题,这个问题隐藏得比较深。当我们使用iPad或其他常规宽度的设备时,就会得到一个运行时异常:Terminating app due to uncaught exception ‘NSGenericException’, reason: ‘UIPopoverPresentationController () should have a non-nil sourceView or barButtonItem set before the presentation occurs.’就如我们之前所说,在常规宽度的设备上,上拉菜单是以弹出框的形式展现。弹出框必须要有一个能够作为源视图或者栏按钮项目的描点(anchor point)。由于在本例中我们是使用了常规的UIButton来触发上拉菜单的,因此我们就将其作为描点。在iOS 8中我们不再需要小心翼翼地计算出弹出框的大小,UIAlertController将会根据设备大小自适应弹出框的大小。并且在iPhone或者紧缩宽度的设备中它将会返回nil值。配置该弹出框的代码如下:Objective-C版本:UIPopoverPresentationController&*popover&=&alertController.popoverPresentationC
if&(popover){
&&&&popover.sourceView&=&
&&&&popover.sourceRect&=&sender.
&&&&popover.permittedArrowDirections&=&UIPopoverArrowDirectionA
}swift版本:var&popover&=&alertController.popoverPresentationController
if&(popover&!=&nil){
&&&&popover?.sourceView&=&sender
&&&&popover?.sourceRect&=&sender.bounds
&&&&popover?.permittedArrowDirections&=&UIPopoverArrowDirection.Any
}iPad上的上拉菜单效果UIPopoverPresentationController类同样也是在iOS 8中新出现的类,用来替换UIPopoverController的。这个时候上拉菜单是以一个固定在源按钮上的弹出框的形式显示的。要注意UIAlertController在使用弹出框的时候自动移除了取消按钮。用户通过点击弹出框的外围部分来实现取消操作,因此取消按钮便不再必需。释放对话框控制器通常情况下,当用户选中一个动作后对话框控制器将会自行释放。不过您仍然可以在需要的时候以编程方式释放它,就像释放其他视图控制器一样。您应当在应用程序转至后台运行时移除对话框或者上拉菜单。假定我们正在监听UIApplicationDidEnterBackgroundNotification通知消息,我们可以在observer中释放任何显示出来的视图控制器。(参考在viewDidLoad方法中设立observer的示例代码)。Objective-C版本:-&(void)didEnterBackground:(NSNotification&*)notification
&&[[NSNotificationCenter&defaultCenter]&removeObserver:self&name:UITextFieldTextDidChangeNotification&object:nil];
&&[self.presentedViewController&dismissViewControllerAnimated:NO&completion:nil];
}swift版本:func&didEnterackground(notification:&NSNotification){
&&&&NSNotificationCenter.defaultCenter().removeObserver(self,&name:&UITextFieldTextDidChangeNotification,&object:&nil)
&&&&self.presentedViewController?.dismissViewControllerAnimated(false,&completion:&nil)
}注意,要保证运行安全我们同样要确保移除所有的文本框observer。我们来总结一下这篇文章比较长,但是希望能够对您有所帮助。原先的UIAlertView和UIActionSheet类仍然可以在iOS 8中工作得很好,所以没有必要急于更换代码(要知道本文用到的许多函数尽在iOS 8中支持)。本文的代码可以在我的Github主页上找到,包括了AlertController - ObjC以及AlertController - swift。
微信扫一扫
订阅每日移动开发及APP推广热点资讯公众号:CocoaChina
您还没有登录!请或
点击量4849点击量4404点击量3835点击量3456点击量3217点击量3180点击量3133点击量2980点击量2812
&2016 Chukong Technologies,Inc.
京公网安备89

我要回帖

更多关于 xcode ios8 的文章

 

随机推荐