Mac系统的应用程序使用的是AppKit框架,这里按书里的内容,先对AppKit简单介绍。
在AppKit里面可以看到Cocoa框架中关于用户界面的大量资源。
按《Objective-C 基础教程(第2版)》的范例,这里也用一个大小写转换的App创建过程来举例。
之后选择OS X项下的Cocoa Application图标,创建新项目:
点击Next...
iOS 5.0之后,Apple为开发者提供了Storyboards(故事板)界面,有兴趣的话可以尝试使用,某些情况下确实条理清晰很多。
更多的关于Storyboards以后有空再写吧~
在选择完项目存储路径后,Xcode已经为我们创建好基本的项目文件,还有一个Interface Builder界面:
创建好基础项目后,我们可以看到,显示界面最左侧是项目文件的导航栏,中间是Interface Builder,最右边是检查器和库面板。
如果要配合Interface Builder来打造一个项目,最好就是开启分栏界面,这样的好处是界面和代码能够对比配合:
大屏幕的好处就在这里了,15寸的MBP看起来还是不够大:
进行用户界面布局,因为我们是一个大小写翻译的App,所以应该有一个输入栏。
在库的过滤器中输入text,找到Text Field,用鼠标左键按住拖动到窗口中,然后调整左右大小:
然后转换完就要输出,所以再查找Label,把Label拖入窗口。
这里要注意,Label默认没有底色,并不代表它没有左右宽度。要记得把它设置到合适的大小,否则文字会被截断显示不出来。从下图可以看到,拖动的时候,Xcode是会在需要的时候提供智能参考线的:
接着是两个控制转换为大写和小写的按钮,库中搜索push button,拖进窗口,然后双击文本改成自己需要的:
最后修改整个窗口的大小,以视觉美观为出发点,这样基本的App界面就设计好了:
首先我们要修改AppDelegate.h文件,把IBOutlet关键字的代码写进去(后面还有IBAction关键字)。
但是IBOutlet在这里并不执行任何操作,定义他们的目的是为了给阅读代码的人提供标记,通过查找文件中的IBOutlet和IBAction关键字,可以知道AppDelegate对象拥有两个可以用来连接的实例变量,还提供了两个方法作为按钮的目标。
// AppDelegate.h
#import
@interface AppDelegate : NSObject
@property (assign) IBOutlet NSWindow *window; //可以省略
@end
输入完代码,可以看到该行代码前面有个空心小圆圈被填充,说明已经创建了连接:
在刚才创建的用户界面中,有一个文本输入的地方和一个文本输出的地方,要让它们有功能,当然也要创建对应的代码。
下面用Xcode提供的辅助编辑功能来帮我们快速组织代码。
右键点击Text Field文本框,往AppDelegate.h代码编辑区域的合适位置拖拉,直到出现“Insert Outlet or Action”:
注意这里是右键!!右键!!我不知道为什么书里写的是按住Control然后拖拉。。
可能是Xcode 7改了操作方式,折腾了我好久。。
放开右键后会弹出一个对话框,在Name文本框中输入textfield,这个就是代码中的变量名。
对话框中会把变量的类型和属性都安排好:
点击Connect,代码将自动生成并建立连接:
同时还要创建连接的有Label栏,用相同的步骤操作后,AppDelegate.h代码如下:
#import
@interface AppDelegate : NSObject
@property (assign) IBOutlet NSWindow *window;
@property (weak) IBOutlet NSTextField *textfield;
@property (weak) IBOutlet NSTextField *resultfield;
@end
现在,我们要把按钮连接到操作,这样按钮被按下的时候就会触发代码。
仍然是依次用右键点击UpperCase和LowerCase按钮并拖动到AppDelegate.h文件的代码区,自动创建代码。
但在弹出的对话框中,必须把连接类型改为Action,并把变量名设置为uppercase和lowercase:
完成后,AppDelegate.h代码如下:
#import
@interface AppDelegate : NSObject
@property (assign) IBOutlet NSWindow *window;
@property (weak) IBOutlet NSTextField *textfield;
@property (weak) IBOutlet NSTextField *resultfield;
- (IBAction)uppercase:(id)sender;
- (IBAction)lowercase:(id)sender;
@end
一个常见的错误:
试图在init方法中使用IBOutlet执行一些操作。
由于所有实例变量都为nil,所有发送给它们的消息都不会执行操作,所以在init方法中尝试任何关于IBOutlet的操作都会无疾而终)。
如果想知道为什么这些操作不起作用,可以使用NSLog输出实例变量的值,查看它们是否都是nil。
添加一个init方法,通过它在初始化时显示IBOutlet实例变量的值:
- (id)init
{
if (nil != (self = [super init])){
NSLog (@"init: text %@ / results %@", _textfield, _resultfield);
}
return self;
}
为了让用户界面更科学,美观又容易读懂,我们应该将文本框的默认内容设置为提示性质的。
使用awakeFromNib方法来执行这个任务很合适:
- (void)awakeFromNib
{
NSLog (@"awake: text %@ / results %@", _textfield, _resultfield);
//NStextField类的setStringValue:方法
//接收一个NSString作为参数并更改接收该方法的变量的值
[_textfield setStringValue:@"Enter text here"];
[_resultfield setStringValue:@"Results"];
}
利用NStextField类的setStringValue:方法,用于点击按钮后的输出我们想要的字符:
- (IBAction)uppercase:(id)sender {
NSString *original = [_textfield stringValue];
NSString *uppercase = [original uppercaseString];
[_resultfield setStringValue:uppercase];
}
- (IBAction)lowercase:(id)sender {
NSString *original = [_textfield stringValue];
NSString *lowercase = [original lowercaseString];
[_resultfield setStringValue:lowercase];
}
整个APPDelegate.m的代码如下:
#import "AppDelegate.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
- (id)init
{
if (nil != (self = [super init]))
{
NSLog (@"init: text %@ / results %@", _textfield, _resultfield);
}
return self;
}
- (void)awakeFromNib
{
NSLog (@"awake: text %@ / results %@", _textfield, _resultfield);
[_textfield setStringValue:@"Enter text here..."];
[_resultfield setStringValue:@"Results:"];
}
- (IBAction)uppercase:(id)sender {
NSString *original = [_textfield stringValue];
NSString *uppercase = [original uppercaseString];
[_resultfield setStringValue:uppercase];
}
- (IBAction)lowercase:(id)sender {
NSString *original = [_textfield stringValue];
NSString *lowercase = [original lowercaseString];
[_resultfield setStringValue:lowercase];
}
@end
点击Run按钮,Xcode将项目编译并运行,然后弹出App的初始界面:
输入英文文本并点击按钮测试。
点击UpperCase:
点击LowerCase:
搞定!