Mac OS app 用 StoryBoard開發的一點感想。
前提
最近在學習app的逆向,準備自己搞一個app,然後用逆向工具對其進行惡搞一下。
選擇
糾結在于用Mac app還是 IOS app,糾結了一下,選擇了Mac app。
原因:
-
開發體驗
搞Mac app不用起模拟器。15年的閹割版的Mac跑起模拟器來那叫一個吵和卡。
-
開發效率
電腦不卡,開發效率就會高一點,主要是心情會好,不然太卡的話,寫代碼的時候特别煩。
-
簡單
XCode打開,直接run就好了。
趟坑
-
以為的簡單并不簡單
以為開發來說和和IOS的差不多,但是實際是關于Mac app的開發介紹的文章很少、app 數量也很少
-
在過去Objective-C一直是蘋果生态裡的重要語言,最近幾年雖說主推Swift,但是應該也不至于死掉吧?
沒想到現在用Objective-C開發的實在是太少少了
-
XCode 11
嗯,你沒看錯,就是XCode11,這個版本的XCode UI應該是更新了,是以我能找到的文章都是Objective-C寫的,那時候的XCode UI和現在的UI不一樣
-
StoryBoard
負責UI層展示,這個有很多magic的操作,找不到那就JJ了,完全玩不動呀,當然蘋果現在主推SwiftUI,是以。。。用的時候一直覺的微軟是真的好呀,winform拖控件是真的簡單。
-
給按鈕綁定個單擊事件
我搞了快一天,一直找不到storyboard的UI怎麼和controller關聯起來的,然後自然也找不到按鈕的點選事件
- 如何關聯controller
Mac OS app 用 StoryBoard開發的一點感想
#import <Cocoa/Cocoa.h> @interface ViewController : NSViewController @end
- 如何給按鈕添加點選事件
- 在xcode中打開storyboard檔案,找到你要添加點選事件的按鈕。
- 在左側檔案清單中找到關聯的那個controller,按住option鍵然後點選,出現雙屏,一屏是storyboard,一屏是代碼
- 按住control鍵,點着那個按鈕拖向代碼檔案。
- 出現dialog,填上你的内容
Mac OS app 用 StoryBoard開發的一點感想 -
結束
簡單的gif
Mac OS app 用 StoryBoard開發的一點感想
- 如何關聯controller
-
app的功能
- 一個添加頁面
- 一個清除按鈕,點選之後清除頁面輸入的資料
- 一個确定按鈕,點選之後會将資訊攜帶到詳情展示頁面
- 兩個label,兩個輸入框
- 設定view的背景色
Mac OS app 用 StoryBoard開發的一點感想
- 一個詳情展示頁面
- 展示上個頁面填寫的内容
Mac OS app 用 StoryBoard開發的一點感想
- 展示上個頁面填寫的内容
遇到問題
-
代碼裡如何或者輸入框裡的内容
在ViewController.h中綁定兩個屬性,然後在impl中可以直接使用
做法:還是分屏,然後ctrl拖拽,之後就會生成兩個屬性
// interface
#import <Cocoa/Cocoa.h>
@interface ViewController : NSViewController
@property (weak) IBOutlet NSTextField *nameTextField;
@property (weak) IBOutlet NSTextField *phoneTextField;
@end
//impl
#import "ViewController.h"
@implementation ViewController
@synthesize nameTextField;
@synthesize phoneTextField;
// 擷取姓名輸入框的内容
- (NSString *)getName {
return [nameTextField stringValue];
}
// 擷取手機号輸入框的内容
- (NSString *)getPhone {
return [phoneTextField stringValue];
}
//清除輸入框内容
- (IBAction)CancelClicked:(id)sender {
[nameTextField setStringValue:@""];
[phoneTextField setStringValue:@""];
}
// other code
@end
-
如何設定背景色
拓展NSView,添加設定背景色方法,然後綁定到UI層,
- 實作代碼
// interface
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
@interface NSView (backGroundColor)
-(void) setBackGroundColor: (NSColor *) color;
@end
//impl
#import "backgroundColor.h"
@implementation NSView (backgroundColor)
- (void)setBackGroundColor:(NSColor *)color {
[self setWantsLayer:YES];
self.layer = [CALayer layer];
[self.layer setBackgroundColor:[color CGColor]];
}
@end
-
綁定
輸入名稱和拓展的方法一緻,省掉set方法
-
如何點選确定跳轉到另一個界面呢
在storyboard界面找到按鈕,ctrl拖到它點選之後要跳轉的界面
之後出現這個dialog
這樣就完成了。
-
如何将值傳過去呢
先看一下兩個界面之間建立了啥
Mac OS app 用 StoryBoard開發的一點感想
是個NSStoryboardSegue類型的東西
@interface NSStoryboardSegue : NSObject
/* NSStoryboardSegue instances have optional identifiers that can be assigned in Interface Builder. These identifiers can be used in overrides of -[NSViewController prepareForSegue:sender:] to differentiate segues. */
@property (nullable, readonly, copy) NSStoryboardSegueIdentifier identifier;
/* Subclasses of NSStoryboardSegue can use this property to access the source view or window controller that is being segued away from. */
@property (readonly, strong) id sourceController;
/* Subclasses of NSStoryboardSegue can use this property to access the destination view or window controller that\'s being segued to. This property is also essential for overrides of -[NSViewController prepareForSegue:sender:], which is passed to the source view controller. This property allows the receiver of -[NSViewController prepareForSegue:sender:] to access and pass configuration data to the destination controller. */
@property (readonly, strong) id destinationController;
@end
有sourceController和destinationController,是不是很明确了
-
步驟
1. 重寫SourceController(
)的NSViewController
方法- (void)prepareForSegue:(NSStoryboardSegue *)segue sender:(nullable id)sender
```objective-c
- (void)prepareForSegue:(NSStoryboardSegue *)segue sender:(nullable id)sender {
DetailController *detailController = [[DetailController alloc] init]; // destinationController
detailController = segue.destinationController;
UserInfo *userInfo = [[UserInfo alloc] init];
[userInfo setName:[self getName] andPhone:[self getPhone]];
detailController.userInfo= userInfo;//設定要傳遞的值
}
```
2. destinationController
添加一個屬性接收傳遞的值,在`viewDidLoad`方法裡将傳遞的值給指派到view上
```objective-c
// interface
@interface DetailController : NSViewController
@property UserInfo *userInfo;
@property (weak) IBOutlet NSTextField *nameTextField;
@property (weak) IBOutlet NSTextField *phoneTextField;
@end
// impl
@implementation DetailController
@synthesize userInfo;
@synthesize nameTextField;
@synthesize phoneTextField;
- (void)viewDidLoad {
[super viewDidLoad];
[nameTextField setStringValue:[userInfo name]];
[phoneTextField setStringValue:[userInfo phone]];
}
@end
```
結束
遇到錯誤
resource fork, Finder information, or similar detritus not allowed
Command CodeSign failed with a nonzero exit code
解決方法:進入項目的根目錄執行
xattr -cr .
引用
- Mac Os DarkMode
- iOS - Code Sign Error in macOS High Sierra Xcode - resource fork, Finder information, or similar detritus not allowed - Stack Overflow
源碼
https://github.com/1483523635/simple-MacOS-app
部落格原始位址
https://github.com/1483523635/blogs/blob/master/MacOSApp/StoryBoard.md