SlideShare a Scribd company logo
1 of 59
Class 07
iOS 應⽤用軟體設計
內容⼤大綱
•   UIScrollView
    •   QV089:圖⽚片捲動

    •   QV090:圖⽚片捲動⽴立即顯⽰示縮放⽐比例

    •   Samples:Scrolling

•   iOS 之多⼯工與⽣生命週期

•   UIApplicationDelegate 的運作

    •   QV100:⽣生命週期的測試及通知
•   Notification 通知

•   應⽤用程式的執⾏行流程

    •   QV037:Empty + SingleView

    •   QV038:Empty (未使⽤用rootViewController)
UIScrollView
UIScrollView


               contentSize
UIScrollViewDelegate
• Instance Methods......
Project QV089



UIScrollView
ViewController.h




#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UIScrollViewDelegate>
{
    UIScrollView *myScrollView;
    UIImageView *myImageView;
}

@end
ViewController.m (1/2)
- (void)viewDidLoad
{
    [super viewDidLoad];

    // 實際完整的內容 (要被縮放的圖形 )
    myImageView = [[UIImageView alloc] initWithImage:[UIImage
                                               imageNamed:@"image.jpg"]];

    // 框起來要顯⽰示的部份
    myScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(10,10,300,440)];

    myScrollView.delegate = self;   // 這列要寫在前⾯面

    // 設定可縮放倍率,把虛擬畫⾯面設定成與 myImageView ⼀一樣⼤大⼩小
    myScrollView.contentSize = myImageView.frame.size;
    myScrollView.minimumZoomScale = 0.2f;
    myScrollView.maximumZoomScale = 2.0f;
    myScrollView.zoomScale = 0.5f;

    // 讓圖形的中⼼心定位在畫⾯面中央
    myScrollView.contentOffset = CGPointMake((myImageView.frame.size.width-300)/2,
                                            (myImageView.frame.size.height-440)/2);
    myScrollView.showsHorizontalScrollIndicator = YES;
    myScrollView.showsVerticalScrollIndicator = YES;
    myScrollView.pagingEnabled = NO;

    [myScrollView addSubview:myImageView];

    // 置於主畫⾯面上
    [self.view addSubview:myScrollView];
}
ViewController.m (2/2)




- (UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return myImageView;
}
Project QV090


擴充 QV089,增加在捲動
完畢後顯⽰示當時的縮放⽐比例
UIScrollView Delegate 使⽤用
ViewController.h




#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UIScrollViewDelegate>
{
    UIScrollView *myScrollView;
    UIImageView *myImageView;
    UILabel *scaleRatioLabel;!// 顯⽰示倍率⽤用的Label
}

@end
ViewController.m (1/2)




                                           放在畫⾯面中央位置
- (void)viewDidLoad
{
    ****** 省略部份程式 ******

    // ⽤用來顯⽰示倍率的 Label
! scaleRatioLabel = [[UILabel alloc]
                 initWithFrame:CGRectMake(160-25,240-12.5,50,25)];
! [scaleRatioLabel setBackgroundColor:[UIColor clearColor]];
! [self.view addSubview:scaleRatioLabel];
}
ViewController.m (2/2)



// 處理結束縮放事件
- (void) scrollViewDidEndZooming:(UIScrollView *)scrollView
                        withView:(UIView *)view atScale:(float)scale
{
! [self.view bringSubviewToFront:scaleRatioLabel];
! [scaleRatioLabel setAlpha:0.6f];
! [scaleRatioLabel setBackgroundColor:[UIColor lightGrayColor]];
! scaleRatioLabel.text = [NSString stringWithFormat:@" x%.1f ",scale];


    [UIView transitionWithView:scaleRatioLabel
                       duration:2.0f
                        options:UIViewAnimationOptionCurveEaseInOut
                     animations:^(void){
                                   scaleRatioLabel.alpha = 0.0f;
                                 }
                     completion:nil];
}
範例:Scolling
iOS 的多⼯工
iOS 多⼯工 (Multitasking)
iOS 3     iOS 4   iOS 5   iOS 6


         • 能夠⽀支援的硬體
          • iPhone:3GS 之後(含)
          • iPod touch:第 3 代之後
          • iPad:每⼀一代均有
iOS 的多⼯工?

• 真/假 多⼯工
 • 佔⽤用記憶體
 • 不佔⽤用 CPU
 • 程式被關閉後
  (釋放部份記憶
  體) 仍能繼續
多⼯工程式的必要


• 聲⾳音播放
• 網路連結 (例如:檔案傳輸)
• 程式持續性 (例如:畫⾯面隨著時間改變)
• 周邊互動 (例如:GPS、藍芽、USB存取)
假多⼯工的優勢
       (相較於真多⼯工)


• 省電 (不佔⽤用 CPU)
• 省記憶體 (釋放後仍能接續執⾏行,故系統
 能夠任意釋放記憶體)

• 順暢 (前景程式可以⽤用到近 100% 的 CPU
 與更多記憶體)
假多⼯工的缺點

• 在背景時,無法執⾏行系統預設允許服務
 以外的程序 (例如⼤大檔傳輸、⾳音樂轉檔)

• 無法同時開啟多個服務 (例如同時播放兩
 ⾸首歌)

• 需要程式撰寫技術 (必須通曉 iOS API 才
 能啟⽤用假多⼯工)
⼿手機......

   假多⼯工才是趨勢
 (需要智慧型資源管理)
補充參考

• iOS 與 Android 的多⼯工機制
  (http://ffk0716.blogspot.com/2011/07/iosandroid.html)

• 為什麼 Android 開始使⽤用假多⼯工
  (http://ffk0716.blogspot.com/2011/12/android.html)
iOS App 之⽣生命週期
iOS App 的狀態改變
程式啟動




進⼊入前景
進⼊入背景




沈睡狀態
進⾏行中程式被中斷
從前景

移到背景
從背景

返回前景
範例:

UIApplicationDelegate 運作
    狀態變更的通知
iOS App 多⼯工的⽣生命週期
•   UIApplicationDelegate
    •   -(BOOL) applicaton: (UIApplication *)application
        didFinishLaunchingWithOptions: (NSDictionary
        *)launchOptions
    •   - (void) applicationWillResignActive:
    •   - (void) applicationDidEnterBackground:
    •   - (void) applicationWillEnterForeground:
    •   - (void) applicationDidBecomeActive:
    •   - (void) applicationWillTerminate:
動作⼀一:初次執⾏行 App

• App 的誕⽣生
 • application:
    didFinishLaunchingWithOptions: 被呼叫

 • 可在此使⼀一些初始化的動作
• 進⼊入 active 狀態
 • applicationDidBecomeAtive: 被呼叫
動作⼆二:按下 home 按鈕
•   進⼊入 inactive 狀態,讓 App 沈睡
    •   applicationWillResignActive: 被呼叫

•   進⼊入背景模式
    •   applicationDidEnterBackground: 被呼叫
    •   只有很短的時間做休息前的最後運算

•   進⼊入冬眠模式
    •   不做動作 (故沒有 method 被呼叫)

    •   在記憶體裡仍保有先前建⽴立的物件
動作三:再次按下 App Icon


• 進⼊入前景模式
 • applicationWillEnterForeground: 被呼叫
• 進⼊入 active 狀態
 • applicationDidBecomeActive: 被呼叫
動作四:進⼊入 lock 狀態
•   進⼊入背景模式

    •   applicationWillResignActive: 被呼叫
    •   applicationWillEnterBackground: 被呼叫

•   注意:在 4.3 版中...

    •   不會進⼊入背景模式,只是進⼊入 inactive 狀
        態

    •   沒有事件被呼叫,⽽而時間仍然繼續在⾛走
動作五:重新開機


• 關機,終⽌止程式
 • applicationWillTerminate: 被呼叫
 • ............. (有什麼需要寫的?)
App 的死亡原因
•   使⽤用者在 home 畫⾯面下,再雙擊 home 進⼊入殺⼿手模
    式,刪除 App
•   開發者製作的 App 有問題,執⾏行到某個地⽅方當掉

•   執⾏行中的 App 佔了太多記憶體,被系統強制殺掉
•   系統的記憶體不⾜足,於是系統會將進⼊入沈睡模式的
    App 殺掉 (佔⽤用愈多記憶體的,優先被刪除)
•   App 在進⼊入背景模式 applicationDidEnterBackground:
    裡頭執⾏行了太⻑⾧長的時間

•   重新開機
程式終⽌止,善盡責任
•   單⼯工時代的 applicationWillTerminate: 很重要,多⼯工
    時代幾乎不⽤用
•   多⼯工後,在 applicationDidEnterBackground: 裡增加
    ⼀一些預防措施

•   經常狀況
    •   例如:簡訊⽂文字輸⼊入到⼀一半、遊戲進⾏行到哪個關
        卡......應有預先儲存
    •   降低記憶體⽤用量,例如將⼀一些畫⾯面上的 UI 物件
        清除。改採記錄當時的畫⾯面資訊,之後可再還原
Project QV100

UIApplicationDelegate
⽣生命週期的測試
Notification
通知 view controller
AppDelegate.m
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSLog(@"!!! %@", NSStringFromSelector(_cmd));

    *** 省略部份程式 ***
}                                                指定各處使⽤用相同的程式
- (void)applicationWillResignActive:(UIApplication *)application
{
    NSLog(@"!!! %@", NSStringFromSelector(_cmd));
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    NSLog(@"!!! %@", NSStringFromSelector(_cmd));
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
    NSLog(@"!!! %@", NSStringFromSelector(_cmd));
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
   NSLog(@"!!! %@", NSStringFromSelector(_cmd));
}
- (void)applicationWillTerminate:(UIApplication *)application
{
    NSLog(@"!!! %@", NSStringFromSelector(_cmd));
}
ViewController.h

Notification 的測試



 #import <UIKit/UIKit.h>

 @interface ViewController : UIViewController
 {
     int count;
     IBOutlet UILabel *display;
 }

 -(void)sayGoodBye:(NSNotification*)notification;
 -(void)sayHello:(NSNotification*)notification;

 @end
ViewController.m (1/2)
進⼊入背景狀態的通知


-(void)sayGoodBye:(NSNotification*)notification
{
    NSLog(@"Say GoodBye from %@", notification);
    display.text = @"Good Bye";
}


- (void)viewDidLoad
{
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter]
             addObserver:self
                selector:@selector(sayGoodBye:)
                    name:UIApplicationWillResignActiveNotification
                  object:[UIApplication sharedApplication]];
}
ViewController.m (2/2)
    返回前景狀態的通知

-(void)sayHello:(NSNotification*)notification
{
    NSLog(@"Say Hello from %@", notification);
    count++;
    display.text = [NSString stringWithFormat:
                    @"Hello ⼜又⾒見⾯面啦!這是第 %d 次重相⾒見", count];
}


- (void)viewDidLoad
{
    *** 省略部份程式 ***

    count = 1;
    [[NSNotificationCenter defaultCenter]
             addObserver:self
                selector:@selector(sayHello:)
                    name:UIApplicationWillEnterForegroundNotification
                  object:[UIApplication sharedApplication]];
}
Notification
狀態變更的通知

• 狀態變更的通知 (notification)
• UIApplicationDelegate 最清楚,但⼤大部份
 時候,控制畫⾯面顯⽰示內容的,卻是 view
 controller,故需要被通知

• notification 機制可⽤用在任何物件 (不只是
 view controller)
• ⽤用法:由物件申請在狀態發⽣生時被通知
Notification 名稱

   UIApplicationDelegate method                         Notification 名稱
application:didFinishLaunchingWithOptions:   UIApplicationDidFinishLaunchingNotification

applicationWillResignActive:                 UIApplicationWillResignActiveNotification

applicationDidBecomeActive:                  UIApplicationDidBecomeActiveNotification

applicationDidEnterBackground:               UIApplicationDidEnterBackgroundNotification

applicationWillEnterForeground:              UIApplicationWillEnterForegroundNotification

applicationWillTerminate:                    UIApplicationWillTerminateNotification
享有背景⼯工作的特權
•   無時間限制 (Multitasking)

    •   位置追蹤
    •   ⾳音樂播放

    •   VOIP
•   GCD (Grand Center Dispatch)
    •   開發者可⾃自訂程式功能 (有時間限制)

    •   beginBackgroundTaskWithExpirationHandler:
應⽤用程式的執⾏行流程
Project QV037
從樣版 Empty Application
新增⼀一個專案,在上⾯面切
換到另⼀一個 View 畫⾯面
此範例中⾃自訂NextView,
其實就相當於SingleView
Application專案中的
ViewController
從全新的空⽩白專案開始
選擇 File -> New -> File......
新增加檔案:NextView.h, NextView.m, NextView.xib
AppDelegate.h



                   @class⽤用法在於告訴編譯器,有⼀一個
                   類別 NextView。也可以改⽤用
                   #import "NextView.h"


#import <UIKit/UIKit.h>

@class NextView;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) NextView *nextView;

@end
AppDelegate.m
#import "AppDelegate.h"

#import "NextView.h"

@implementation AppDelegate
                                                新增加的程式碼
@synthesize window = _window;
@synthesize nextView = _nextView;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:
(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.

    self.nextView = [[NextView alloc] initWithNibName:@"NextView" bundle:nil];
    self.window.rootViewController = self.nextView;

    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

// 部分程式省略

@end
問題
NextView是設為AppDelegate的
rootViewController,⼀一定要這樣指定
嗎?
原本的rootViewController存在嗎?
若是改⽤用addSubView或是其他切換⽅方式
可⾏行嗎?
Project QV038

同QV037
從樣版 Empty Application
新增⼀一個專案,利⽤用程式
增加⼀一個view及內容
不建議直接在window上增
加畫⾯面
#import "AppDelegate.h"                                   AppDelegate.m
@implementation AppDelegate

@synthesize window = _window;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:
(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor blueColor];

    // 開始⼀一個view
    UIView* view = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,480)];

    UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    [label setFont:[UIFont boldSystemFontOfSize:18]];
    [label setTextAlignment:UITextAlignmentCenter];
    [label setBackgroundColor:[UIColor clearColor]];
    [label setTextColor:[UIColor whiteColor]];
    [label setText:@"Hello"];
    [view addSubview:label];
    [_window addSubview:view];

    [self.window makeKeyAndVisible];
    return YES;
}
                                                    只在此檔案內加⼊入此段
                                                    程式,其餘都沒動
補充
⽅方法參考:How to add a simple new
UIView in a window based application
programmatically in iphone。
http://stackoverflow.com/questions/801426/how-to-add-a-simple-new-uiview-in-
a-window-based-application-programmatically-in


為什麼不好?
正確⽅方法參考 QV037;或直接產⽣生
SingleView 的 Application 專案
......

More Related Content

Viewers also liked (12)

I os 11
I os 11I os 11
I os 11
 
I os 16
I os 16I os 16
I os 16
 
I os 02
I os 02I os 02
I os 02
 
I os 06
I os 06I os 06
I os 06
 
I os 08
I os 08I os 08
I os 08
 
I os 05
I os 05I os 05
I os 05
 
I os 04
I os 04I os 04
I os 04
 
I os 14
I os 14I os 14
I os 14
 
I os 15
I os 15I os 15
I os 15
 
I os 03
I os 03I os 03
I os 03
 
課程規畫
課程規畫課程規畫
課程規畫
 
I os 13
I os 13I os 13
I os 13
 

Similar to I os 07

Android 智慧型手機程式設計
Android 智慧型手機程式設計Android 智慧型手機程式設計
Android 智慧型手機程式設計Kyle Lin
 
07 View Controllers
07 View Controllers07 View Controllers
07 View ControllersTom Fan
 
怎樣在 Flutter app 中使用 Google Maps
怎樣在 Flutter app 中使用 Google Maps怎樣在 Flutter app 中使用 Google Maps
怎樣在 Flutter app 中使用 Google MapsWeizhong Yang
 
08 Notification and Rotation
08 Notification and Rotation08 Notification and Rotation
08 Notification and RotationTom Fan
 
[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式Shengyou Fan
 
透過 Windows Azure Mobile Services 開發各平台 Apps
透過 Windows Azure Mobile Services 開發各平台 Apps透過 Windows Azure Mobile Services 開發各平台 Apps
透過 Windows Azure Mobile Services 開發各平台 AppsEric ShangKuan
 
2016輕鬆開發自有網路地圖工作坊 進階班 0701
2016輕鬆開發自有網路地圖工作坊 進階班 07012016輕鬆開發自有網路地圖工作坊 進階班 0701
2016輕鬆開發自有網路地圖工作坊 進階班 0701family
 
給 iOS 工程師的 Flutter 開發
給 iOS 工程師的 Flutter 開發給 iOS 工程師的 Flutter 開發
給 iOS 工程師的 Flutter 開發Weizhong Yang
 
利用Signalr打造即時通訊@Tech day geek
利用Signalr打造即時通訊@Tech day geek利用Signalr打造即時通訊@Tech day geek
利用Signalr打造即時通訊@Tech day geekJohnson Gau
 
YUIconf2010介绍
YUIconf2010介绍YUIconf2010介绍
YUIconf2010介绍ling yu
 
Android应用开发 - 沈大海
Android应用开发 - 沈大海Android应用开发 - 沈大海
Android应用开发 - 沈大海Shaoning Pan
 
Backbone.js and MVW 101
Backbone.js and MVW 101Backbone.js and MVW 101
Backbone.js and MVW 101Jollen Chen
 
Uliweb cheat sheet_0.1
Uliweb cheat sheet_0.1Uliweb cheat sheet_0.1
Uliweb cheat sheet_0.1modou li
 
Spring 2.x 中文
Spring 2.x 中文Spring 2.x 中文
Spring 2.x 中文Guo Albert
 
Html5移动网站开发实践
Html5移动网站开发实践Html5移动网站开发实践
Html5移动网站开发实践Web Zhao
 
Script with engine
Script with engineScript with engine
Script with engineWebrebuild
 
JavaScript Code Quality
JavaScript Code QualityJavaScript Code Quality
JavaScript Code QualityJoseph Chiang
 
HTML+COIMOTION 開發跨平台 app
HTML+COIMOTION 開發跨平台 appHTML+COIMOTION 開發跨平台 app
HTML+COIMOTION 開發跨平台 appBen Lue
 

Similar to I os 07 (20)

005
005005
005
 
Android 智慧型手機程式設計
Android 智慧型手機程式設計Android 智慧型手機程式設計
Android 智慧型手機程式設計
 
07 View Controllers
07 View Controllers07 View Controllers
07 View Controllers
 
怎樣在 Flutter app 中使用 Google Maps
怎樣在 Flutter app 中使用 Google Maps怎樣在 Flutter app 中使用 Google Maps
怎樣在 Flutter app 中使用 Google Maps
 
08 Notification and Rotation
08 Notification and Rotation08 Notification and Rotation
08 Notification and Rotation
 
[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
[GDG Kaohsiung DevFest 2023] 以 Compose 及 Kotlin Multiplatform 打造多平台應用程式
 
透過 Windows Azure Mobile Services 開發各平台 Apps
透過 Windows Azure Mobile Services 開發各平台 Apps透過 Windows Azure Mobile Services 開發各平台 Apps
透過 Windows Azure Mobile Services 開發各平台 Apps
 
2016輕鬆開發自有網路地圖工作坊 進階班 0701
2016輕鬆開發自有網路地圖工作坊 進階班 07012016輕鬆開發自有網路地圖工作坊 進階班 0701
2016輕鬆開發自有網路地圖工作坊 進階班 0701
 
給 iOS 工程師的 Flutter 開發
給 iOS 工程師的 Flutter 開發給 iOS 工程師的 Flutter 開發
給 iOS 工程師的 Flutter 開發
 
利用Signalr打造即時通訊@Tech day geek
利用Signalr打造即時通訊@Tech day geek利用Signalr打造即時通訊@Tech day geek
利用Signalr打造即時通訊@Tech day geek
 
YUIconf2010介绍
YUIconf2010介绍YUIconf2010介绍
YUIconf2010介绍
 
Android应用开发 - 沈大海
Android应用开发 - 沈大海Android应用开发 - 沈大海
Android应用开发 - 沈大海
 
Backbone.js and MVW 101
Backbone.js and MVW 101Backbone.js and MVW 101
Backbone.js and MVW 101
 
Uliweb cheat sheet_0.1
Uliweb cheat sheet_0.1Uliweb cheat sheet_0.1
Uliweb cheat sheet_0.1
 
Spring 2.x 中文
Spring 2.x 中文Spring 2.x 中文
Spring 2.x 中文
 
Html5移动网站开发实践
Html5移动网站开发实践Html5移动网站开发实践
Html5移动网站开发实践
 
Ios
IosIos
Ios
 
Script with engine
Script with engineScript with engine
Script with engine
 
JavaScript Code Quality
JavaScript Code QualityJavaScript Code Quality
JavaScript Code Quality
 
HTML+COIMOTION 開發跨平台 app
HTML+COIMOTION 開發跨平台 appHTML+COIMOTION 開發跨平台 app
HTML+COIMOTION 開發跨平台 app
 

More from 信嘉 陳

More from 信嘉 陳 (12)

Processing 06
Processing 06Processing 06
Processing 06
 
Processing 05
Processing 05Processing 05
Processing 05
 
Processing 04
Processing 04Processing 04
Processing 04
 
Processing 03
Processing 03Processing 03
Processing 03
 
Processing 02
Processing 02Processing 02
Processing 02
 
Processing 01
Processing 01Processing 01
Processing 01
 
Processing 09
Processing 09Processing 09
Processing 09
 
Processing 08
Processing 08Processing 08
Processing 08
 
Processing 07
Processing 07Processing 07
Processing 07
 
Google 街景
Google 街景Google 街景
Google 街景
 
社群網站 Facebook
社群網站 Facebook社群網站 Facebook
社群網站 Facebook
 
網路搜尋
網路搜尋網路搜尋
網路搜尋
 

I os 07

  • 2. 內容⼤大綱 • UIScrollView • QV089:圖⽚片捲動 • QV090:圖⽚片捲動⽴立即顯⽰示縮放⽐比例 • Samples:Scrolling • iOS 之多⼯工與⽣生命週期 • UIApplicationDelegate 的運作 • QV100:⽣生命週期的測試及通知 • Notification 通知 • 應⽤用程式的執⾏行流程 • QV037:Empty + SingleView • QV038:Empty (未使⽤用rootViewController)
  • 4. UIScrollView contentSize
  • 7. ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController <UIScrollViewDelegate> { UIScrollView *myScrollView; UIImageView *myImageView; } @end
  • 8. ViewController.m (1/2) - (void)viewDidLoad { [super viewDidLoad]; // 實際完整的內容 (要被縮放的圖形 ) myImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"image.jpg"]]; // 框起來要顯⽰示的部份 myScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(10,10,300,440)]; myScrollView.delegate = self; // 這列要寫在前⾯面 // 設定可縮放倍率,把虛擬畫⾯面設定成與 myImageView ⼀一樣⼤大⼩小 myScrollView.contentSize = myImageView.frame.size; myScrollView.minimumZoomScale = 0.2f; myScrollView.maximumZoomScale = 2.0f; myScrollView.zoomScale = 0.5f; // 讓圖形的中⼼心定位在畫⾯面中央 myScrollView.contentOffset = CGPointMake((myImageView.frame.size.width-300)/2, (myImageView.frame.size.height-440)/2); myScrollView.showsHorizontalScrollIndicator = YES; myScrollView.showsVerticalScrollIndicator = YES; myScrollView.pagingEnabled = NO; [myScrollView addSubview:myImageView]; // 置於主畫⾯面上 [self.view addSubview:myScrollView]; }
  • 9. ViewController.m (2/2) - (UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView { return myImageView; }
  • 11. ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController <UIScrollViewDelegate> { UIScrollView *myScrollView; UIImageView *myImageView; UILabel *scaleRatioLabel;!// 顯⽰示倍率⽤用的Label } @end
  • 12. ViewController.m (1/2) 放在畫⾯面中央位置 - (void)viewDidLoad { ****** 省略部份程式 ****** // ⽤用來顯⽰示倍率的 Label ! scaleRatioLabel = [[UILabel alloc] initWithFrame:CGRectMake(160-25,240-12.5,50,25)]; ! [scaleRatioLabel setBackgroundColor:[UIColor clearColor]]; ! [self.view addSubview:scaleRatioLabel]; }
  • 13. ViewController.m (2/2) // 處理結束縮放事件 - (void) scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale { ! [self.view bringSubviewToFront:scaleRatioLabel]; ! [scaleRatioLabel setAlpha:0.6f]; ! [scaleRatioLabel setBackgroundColor:[UIColor lightGrayColor]]; ! scaleRatioLabel.text = [NSString stringWithFormat:@" x%.1f ",scale]; [UIView transitionWithView:scaleRatioLabel duration:2.0f options:UIViewAnimationOptionCurveEaseInOut animations:^(void){ scaleRatioLabel.alpha = 0.0f; } completion:nil]; }
  • 16. iOS 多⼯工 (Multitasking) iOS 3 iOS 4 iOS 5 iOS 6 • 能夠⽀支援的硬體 • iPhone:3GS 之後(含) • iPod touch:第 3 代之後 • iPad:每⼀一代均有
  • 17. iOS 的多⼯工? • 真/假 多⼯工 • 佔⽤用記憶體 • 不佔⽤用 CPU • 程式被關閉後 (釋放部份記憶 體) 仍能繼續
  • 18. 多⼯工程式的必要 • 聲⾳音播放 • 網路連結 (例如:檔案傳輸) • 程式持續性 (例如:畫⾯面隨著時間改變) • 周邊互動 (例如:GPS、藍芽、USB存取)
  • 19. 假多⼯工的優勢 (相較於真多⼯工) • 省電 (不佔⽤用 CPU) • 省記憶體 (釋放後仍能接續執⾏行,故系統 能夠任意釋放記憶體) • 順暢 (前景程式可以⽤用到近 100% 的 CPU 與更多記憶體)
  • 20. 假多⼯工的缺點 • 在背景時,無法執⾏行系統預設允許服務 以外的程序 (例如⼤大檔傳輸、⾳音樂轉檔) • 無法同時開啟多個服務 (例如同時播放兩 ⾸首歌) • 需要程式撰寫技術 (必須通曉 iOS API 才 能啟⽤用假多⼯工)
  • 21. ⼿手機...... 假多⼯工才是趨勢 (需要智慧型資源管理)
  • 22. 補充參考 • iOS 與 Android 的多⼯工機制 (http://ffk0716.blogspot.com/2011/07/iosandroid.html) • 為什麼 Android 開始使⽤用假多⼯工 (http://ffk0716.blogspot.com/2011/12/android.html)
  • 30. 範例: UIApplicationDelegate 運作 狀態變更的通知
  • 31. iOS App 多⼯工的⽣生命週期 • UIApplicationDelegate • -(BOOL) applicaton: (UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions • - (void) applicationWillResignActive: • - (void) applicationDidEnterBackground: • - (void) applicationWillEnterForeground: • - (void) applicationDidBecomeActive: • - (void) applicationWillTerminate:
  • 32. 動作⼀一:初次執⾏行 App • App 的誕⽣生 • application: didFinishLaunchingWithOptions: 被呼叫 • 可在此使⼀一些初始化的動作 • 進⼊入 active 狀態 • applicationDidBecomeAtive: 被呼叫
  • 33. 動作⼆二:按下 home 按鈕 • 進⼊入 inactive 狀態,讓 App 沈睡 • applicationWillResignActive: 被呼叫 • 進⼊入背景模式 • applicationDidEnterBackground: 被呼叫 • 只有很短的時間做休息前的最後運算 • 進⼊入冬眠模式 • 不做動作 (故沒有 method 被呼叫) • 在記憶體裡仍保有先前建⽴立的物件
  • 34. 動作三:再次按下 App Icon • 進⼊入前景模式 • applicationWillEnterForeground: 被呼叫 • 進⼊入 active 狀態 • applicationDidBecomeActive: 被呼叫
  • 35. 動作四:進⼊入 lock 狀態 • 進⼊入背景模式 • applicationWillResignActive: 被呼叫 • applicationWillEnterBackground: 被呼叫 • 注意:在 4.3 版中... • 不會進⼊入背景模式,只是進⼊入 inactive 狀 態 • 沒有事件被呼叫,⽽而時間仍然繼續在⾛走
  • 36. 動作五:重新開機 • 關機,終⽌止程式 • applicationWillTerminate: 被呼叫 • ............. (有什麼需要寫的?)
  • 37. App 的死亡原因 • 使⽤用者在 home 畫⾯面下,再雙擊 home 進⼊入殺⼿手模 式,刪除 App • 開發者製作的 App 有問題,執⾏行到某個地⽅方當掉 • 執⾏行中的 App 佔了太多記憶體,被系統強制殺掉 • 系統的記憶體不⾜足,於是系統會將進⼊入沈睡模式的 App 殺掉 (佔⽤用愈多記憶體的,優先被刪除) • App 在進⼊入背景模式 applicationDidEnterBackground: 裡頭執⾏行了太⻑⾧長的時間 • 重新開機
  • 38. 程式終⽌止,善盡責任 • 單⼯工時代的 applicationWillTerminate: 很重要,多⼯工 時代幾乎不⽤用 • 多⼯工後,在 applicationDidEnterBackground: 裡增加 ⼀一些預防措施 • 經常狀況 • 例如:簡訊⽂文字輸⼊入到⼀一半、遊戲進⾏行到哪個關 卡......應有預先儲存 • 降低記憶體⽤用量,例如將⼀一些畫⾯面上的 UI 物件 清除。改採記錄當時的畫⾯面資訊,之後可再還原
  • 40. AppDelegate.m - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSLog(@"!!! %@", NSStringFromSelector(_cmd)); *** 省略部份程式 *** } 指定各處使⽤用相同的程式 - (void)applicationWillResignActive:(UIApplication *)application { NSLog(@"!!! %@", NSStringFromSelector(_cmd)); } - (void)applicationDidEnterBackground:(UIApplication *)application { NSLog(@"!!! %@", NSStringFromSelector(_cmd)); } - (void)applicationWillEnterForeground:(UIApplication *)application { NSLog(@"!!! %@", NSStringFromSelector(_cmd)); } - (void)applicationDidBecomeActive:(UIApplication *)application { NSLog(@"!!! %@", NSStringFromSelector(_cmd)); } - (void)applicationWillTerminate:(UIApplication *)application { NSLog(@"!!! %@", NSStringFromSelector(_cmd)); }
  • 41. ViewController.h Notification 的測試 #import <UIKit/UIKit.h> @interface ViewController : UIViewController { int count; IBOutlet UILabel *display; } -(void)sayGoodBye:(NSNotification*)notification; -(void)sayHello:(NSNotification*)notification; @end
  • 42. ViewController.m (1/2) 進⼊入背景狀態的通知 -(void)sayGoodBye:(NSNotification*)notification { NSLog(@"Say GoodBye from %@", notification); display.text = @"Good Bye"; } - (void)viewDidLoad { [super viewDidLoad]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sayGoodBye:) name:UIApplicationWillResignActiveNotification object:[UIApplication sharedApplication]]; }
  • 43. ViewController.m (2/2) 返回前景狀態的通知 -(void)sayHello:(NSNotification*)notification { NSLog(@"Say Hello from %@", notification); count++; display.text = [NSString stringWithFormat: @"Hello ⼜又⾒見⾯面啦!這是第 %d 次重相⾒見", count]; } - (void)viewDidLoad { *** 省略部份程式 *** count = 1; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sayHello:) name:UIApplicationWillEnterForegroundNotification object:[UIApplication sharedApplication]]; }
  • 45. 狀態變更的通知 • 狀態變更的通知 (notification) • UIApplicationDelegate 最清楚,但⼤大部份 時候,控制畫⾯面顯⽰示內容的,卻是 view controller,故需要被通知 • notification 機制可⽤用在任何物件 (不只是 view controller) • ⽤用法:由物件申請在狀態發⽣生時被通知
  • 46. Notification 名稱 UIApplicationDelegate method Notification 名稱 application:didFinishLaunchingWithOptions: UIApplicationDidFinishLaunchingNotification applicationWillResignActive: UIApplicationWillResignActiveNotification applicationDidBecomeActive: UIApplicationDidBecomeActiveNotification applicationDidEnterBackground: UIApplicationDidEnterBackgroundNotification applicationWillEnterForeground: UIApplicationWillEnterForegroundNotification applicationWillTerminate: UIApplicationWillTerminateNotification
  • 47. 享有背景⼯工作的特權 • 無時間限制 (Multitasking) • 位置追蹤 • ⾳音樂播放 • VOIP • GCD (Grand Center Dispatch) • 開發者可⾃自訂程式功能 (有時間限制) • beginBackgroundTaskWithExpirationHandler:
  • 49. Project QV037 從樣版 Empty Application 新增⼀一個專案,在上⾯面切 換到另⼀一個 View 畫⾯面 此範例中⾃自訂NextView, 其實就相當於SingleView Application專案中的 ViewController
  • 51. 選擇 File -> New -> File...... 新增加檔案:NextView.h, NextView.m, NextView.xib
  • 52.
  • 53. AppDelegate.h @class⽤用法在於告訴編譯器,有⼀一個 類別 NextView。也可以改⽤用 #import "NextView.h" #import <UIKit/UIKit.h> @class NextView; @interface AppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) NextView *nextView; @end
  • 54. AppDelegate.m #import "AppDelegate.h" #import "NextView.h" @implementation AppDelegate 新增加的程式碼 @synthesize window = _window; @synthesize nextView = _nextView; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. self.nextView = [[NextView alloc] initWithNibName:@"NextView" bundle:nil]; self.window.rootViewController = self.nextView; self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; return YES; } // 部分程式省略 @end
  • 56. Project QV038 同QV037 從樣版 Empty Application 新增⼀一個專案,利⽤用程式 增加⼀一個view及內容 不建議直接在window上增 加畫⾯面
  • 57. #import "AppDelegate.h" AppDelegate.m @implementation AppDelegate @synthesize window = _window; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.backgroundColor = [UIColor blueColor]; // 開始⼀一個view UIView* view = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,480)]; UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; [label setFont:[UIFont boldSystemFontOfSize:18]]; [label setTextAlignment:UITextAlignmentCenter]; [label setBackgroundColor:[UIColor clearColor]]; [label setTextColor:[UIColor whiteColor]]; [label setText:@"Hello"]; [view addSubview:label]; [_window addSubview:view]; [self.window makeKeyAndVisible]; return YES; } 只在此檔案內加⼊入此段 程式,其餘都沒動
  • 58. 補充 ⽅方法參考:How to add a simple new UIView in a window based application programmatically in iphone。 http://stackoverflow.com/questions/801426/how-to-add-a-simple-new-uiview-in- a-window-based-application-programmatically-in 為什麼不好? 正確⽅方法參考 QV037;或直接產⽣生 SingleView 的 Application 專案