2012年9月15日 星期六

全域變數的使用

一個在Xcode上使用全域變數的範例,本例從前一篇文字檔讀取方法修改而來,將讀取到資料當作全域變數來傳遞。此處是利用Delegate來作全域變數的傳遞。

1.新增一個UIViewController到storyBoard,並在此加上一個TextView及Button,原來的ViewController也加上一個Button來控制轉換Page的移動

2.從Page2的Button拉一個Segue到新的UIViewController

3. 新增一個Class檔來對應新的UIViewController


4. 修改新的UIViewController的 Class來對應到page2ViewController檔案

5. 註冊 storyBoard的元件到page2ViewController.h

6.在fileReadAppDelegate.h加上全域變數

#import <UIKit/UIKit.h>

@interface fileReadAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (nonatomic, retain)   NSMutableArray *globalData;

@end

7. 在fileReadAppDelegate.m加上全域變數的設定
@implementation fileReadAppDelegate

@synthesize globalData;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    return YES;
}

8.在fileReadViewController.h加上Delegate

#import <UIKit/UIKit.h>
#import "fileReadAppDelegate.h"

@interface fileReadViewController : UIViewController

@property (weak, nonatomic) IBOutlet UITextView *textDisplay;
@property (weak, nonatomic) IBOutlet UIButton *readButton;

@property (nonatomic, retain) fileReadAppDelegate *appDelegate;

@end


9. 在fileReadViewController.m加上Delegate的設定
#import "fileReadViewController.h"

@interface fileReadViewController ()

@end

@implementation fileReadViewController
@synthesize textDisplay;
@synthesize readButton;

@synthesize appDelegate;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
  
    appDelegate = (fileReadAppDelegate *)[[UIApplication sharedApplication] delegate];
    appDelegate.globalData = [[NSMutableArray alloc] init];

}

- (void)viewDidUnload
{
    [self setTextDisplay:nil];
    [self setReadButton:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (IBAction)readFileAction:(id)sender {
   
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"txt"];
    if (filePath) {
        NSString *contentOfFile = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
        textDisplay.text = contentOfFile;
       
        [appDelegate.globalData addObject:contentOfFile];
    }
   
    UIFont *font = [UIFont fontWithName:@"BiauKai" size:32];
   
    [textDisplay setFont:[UIFont fontWithName:@"BiauKai" size:32]];
}

@end

10. 在page2ViewController.h增加Delegate的變數
#import <UIKit/UIKit.h>
#import "fileReadAppDelegate.h"

@interface page2ViewController : UIViewController
@property (weak, nonatomic) IBOutlet UITextView *textDisplay2;
@property (weak, nonatomic) IBOutlet UIButton *showButton;

@property (nonatomic, retain) fileReadAppDelegate *appDelegate;

@end

11. 在page2ViewController.m增加Delegate的設定,及全域變數的顯示設定。此處的IBAction要從storyBoard拉過來做聯結。

#import "page2ViewController.h"

@interface page2ViewController ()

@end

@implementation page2ViewController
@synthesize textDisplay2;
@synthesize showButton;

@synthesize appDelegate;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (void)viewDidUnload
{
    [self setTextDisplay2:nil];
    [self setShowButton:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (IBAction)showResult:(id)sender {
    appDelegate = (fileReadAppDelegate *)[[UIApplication sharedApplication] delegate];
    NSString *data =    [appDelegate.globalData objectAtIndex:0];
   
    textDisplay2.text = data;
   
    [textDisplay2 setFont:[UIFont fontWithName:@"BiauKai" size:28]];
}

@end

12.顯示結果如下,前後頁的字體大小稍稍不一樣。



文字檔讀取方法

一個最基本的文字檔讀取方法實作,並將結果顯示在TextView上。

1. 開一個新的專案


2. 將所需要的文字檔及字型檔加入到專案中


3. 將一個 Button及一個TextView拉到storyBoard上,並註冊到fileReadViewController.h上

4. 拉一個Button的IBAction到fileReadViewController.m,並加上所需的程式碼
- (IBAction)readFileAction:(id)sender {
   
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"txt"];
    if (filePath) {
        NSString *contentOfFile = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
        textDisplay.text = contentOfFile;
       
    }
   
    UIFont *font = [UIFont fontWithName:@"BiauKai" size:32];
   
    [textDisplay setFont:[UIFont fontWithName:@"BiauKai" size:32]];
}







5. 字型的設定方式請參考 http://kirenenko-tw.blogspot.tw/2012/09/blog-post_12.html

6. 執行後在按下Button後,就會顯示文字檔的內容到TextView,其中文字並以標楷體字型顯示


2012年9月14日 星期五

AudioPlayer基本實作(二)

承繼前一篇AudioPlayer的方法,實際完成一個更接近實用性的Player。
在這一個實作中,除了播放/暫停及停止的功能外,亦加入了快速前進5秒及倒退5秒的按鍵。
播放時間及進度的顯示當然也是不可缺少的。
因為文字放大後,無法全部顯示在一個畫面中,因此最後並進行了文字與聲音的配合顯示,讓文字根據聲音慢慢地向上捲動。

1. 重新開始一個專案

2. 將mp3加入專案中


3. 將storyBoard加入Label / Button / Slider / TextView,並加入所需的資料及設定,當然還需要對audioPlayerViewController.h進行修改,參考如圖


4. 針對#import <AVFoundation/AVFoundation.h>,需要加入AVFoundation Framework

5. 最後對audioPlayerViewController.m進行程式碼的加入,當然所有元件都需要對應所需的Action聯結,藍色字體為所需增加的程式碼。

#import "audioPlayerViewController.h"

@interface audioPlayerViewController ()

@end

@implementation audioPlayerViewController
@synthesize textDisplay;
@synthesize timeLabel;
@synthesize timeSlider;
@synthesize playButton;
@synthesize stopButton;
@synthesize forwardButton;
@synthesize backwardButton;
@synthesize soundSlider;

@synthesize audioPlayer;
@synthesize songTimer;


int  clicked = 0;

NSInteger *indexNumber = 0;
NSInteger *songLength;

- (void) textScrollPosition
 {
 NSInteger total_time = audioPlayer.duration;
 
 int numLines = textDisplay.contentSize.height/textDisplay.font.leading;
 
 double douration = total_time/numLines; // 一行需幾秒
 
 double width = textDisplay.contentSize.width;
 
 double currentLine = numLines * audioPlayer.currentTime/total_time;
 
 indexNumber = (NSInteger )currentLine * (NSInteger) douration;
 
 NSRange range;
 
 if (songLength > (int) indexNumber *(int)2 )
 {
 range = NSMakeRange (((int)indexNumber*(int)2), 0);
 
 }
 else {
 range = NSMakeRange (songLength, 2);
 
 }
 
 [textDisplay scrollRangeToVisible: range];
 
 }
 
 - (void) showTime:(NSTimeInterval ) time
 {
 NSInteger *min;
 NSInteger *sec;
 
 min = (NSInteger ) time/60;
 
 sec = (NSInteger ) time%60;
 
 timeLabel.text = [NSString stringWithFormat:@"%2.2d:%2.2d",min, sec];
 
 
 [self textScrollPosition];
 
 }
 
 -(void)timeLoader
 
 {
 
 NSTimeInterval time = audioPlayer.currentTime;
 
 timeSlider.value = time;
 
 if (audioPlayer.currentTime == 0)
 [self showTime:audioPlayer.duration];
 else
 [self showTime:audioPlayer.currentTime];
 
 [self textScrollPosition];
 
 }


- (void)viewDidLoad
{
     NSString *myMusic = [[NSBundle mainBundle]pathForResource:@"大悲咒(齊豫)" ofType:@"mp3"];
    
     audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:myMusic] error:NULL];
    
     audioPlayer.numberOfLoops = 0;
    
     audioPlayer.volume = soundSlider.value;
    
     timeSlider.maximumValue = audioPlayer.duration;
    
     songTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(timeLoader) userInfo:nil repeats:YES];
    
    [super viewDidLoad];
   
     textDisplay.editable = NO;
     textDisplay.scrollEnabled = YES;
     textDisplay.showsVerticalScrollIndicator =  YES;
    
     NSRange range;
    
     songLength = textDisplay.text.length;
    
     range = NSMakeRange (songLength-1, 0);
}

- (void)viewDidUnload
{
    [self setTextDisplay:nil];
    [self setTimeLabel:nil];
    [self setTimeSlider:nil];
    [self setPlayButton:nil];
    [self setStopButton:nil];
    [self setForwardButton:nil];
    [self setBackwardButton:nil];
    [self setSoundSlider:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

- (IBAction)playerPlay:(id)sender {
   
    if (clicked == 0) {
        clicked = 1;
       
        [audioPlayer play];
       
        [playButton setTitle:@"暫停" forState:UIControlStateNormal];

    }
    else {
        clicked = 0;
        [audioPlayer pause];
       
        [playButton setTitle:@"播放" forState:UIControlStateNormal];
    }
}

- (IBAction)playerStop:(id)sender {
    [audioPlayer stop];
   
    audioPlayer.currentTime = 0;
   
    clicked = 0;
   
    [playButton setTitle:@"播放" forState:UIControlStateNormal];
   
}
- (IBAction)forward:(id)sender {
    NSTimeInterval time = audioPlayer.currentTime;
   
    time += 5.0;     // forward 5 secs
   
    if (time > audioPlayer.duration)
       
    {
       
        [audioPlayer stop];
       
    }
   
    else
       
        audioPlayer.currentTime = time;
   
    [self textScrollPosition];

}
- (IBAction)backward:(id)sender {
    NSTimeInterval time = audioPlayer.currentTime;
   
    time -=5;
   
    if (time<=0) {
       
        audioPlayer.currentTime = 0.0;
       
    }
   
    else {
       
        audioPlayer.currentTime = time;
       
    }
   
    [self textScrollPosition];
}
- (IBAction)timePosition:(id)sender {
  
    double timeValue = timeSlider.value;
   
    audioPlayer.currentTime = (NSTimeInterval ) timeValue;
   
    [self textScrollPosition];

}
- (IBAction)soundVolume:(id)sender {
   
    audioPlayer.volume = soundSlider.value;
   
}


6. 執行結果參考如圖,聲音無法貼出




2012年9月13日 星期四

APP的ICON設定

任何一個APP在iphone/ipad上一定會有一個ICON,現在就將ICON加到APP上

參考資料http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/App-RelatedResources/App-RelatedResources.html



1. 準備一個57x57pixels的PNG檔及另一個114x114的圖片作為ICON顯示之用,並將檔案拉進專案內



2. 到專案的plist檔,增加Icon的檔名到ICON的設定區,可以有很多的ICON來備選

3. 到專案的Summer區,指定所用ICON是那一個


4. 在Build之前,需要先做Clean的動作,來強制重建。


5. 執行程式,然後縮小畫面(按紅色部分)

6.顯示ICON在iPhone上了


7. 如果想更換ICON,就在Summary區,用滑鼠右鍵來點選

8. 換成另一個ICON(這裡換成紅蘋果)

9. 要記得Clean的動作,再重新Build一次,就可得到更換後的結果了


APP啟動的LOGO設定

APP如何設定一個靜態的啓動

拿前面繪圖實作的例子來添加啟動LOGO,在這裡拿一個台灣地圖來實作

其他細節可參考
http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/App-RelatedResources/App-RelatedResources.html

 http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/mobilehig/IconsImages/IconsImages.html



1. 當然要先將圖檔拉近專案中

2. 將圖檔設定到plist檔中,首先選擇Application Category這個項目

3. 按下“+”號後,選擇Launch Image這個項目


4. 在Launch Image這個項目的後面設定要載入的LOGO圖檔

5. 完成以上設定就可以了,執行APP後,會先出現台灣地圖,再Touch一次才會回到正常的執行畫面。



使用程式來尋找中文字體檔頭

緣由:因中文字形的檔頭與檔名經常不一致,需要一個方式來顯示

程式碼會將此IOS內建字型的檔頭檔名在debug 區顯示出來。(此程式碼只能顯示TTF檔,OFT無效)

 NSArray *familyNames = [[NSArray alloc] initWithArray:[UIFont familyNames]];
   
    NSArray *fontNames;
   
    NSInteger indFamily, indFont;
   
    for (indFamily=0; indFamily<[familyNames count]; ++indFamily)
       
        {
   
            NSLog(@"Family name: %@", [familyNames objectAtIndex:indFamily]);
           
            fontNames = [[NSArray alloc] initWithArray:
                          
                    [UIFont fontNamesForFamilyName:
                             
                    [familyNames objectAtIndex:indFamily]]];
           
            for (indFont=0; indFont<[fontNames count]; ++indFont)
               
                {
                   
                    NSLog(@" Font name: %@", [fontNames objectAtIndex:indFont]);
                   
                }
           
     //  [fontNames release];
           
    }
    // [familyNames release];



顯示結果
娃娃體  檔名Wawa-TC-Regular-stub.ttf      
Family name: Wawati TC
Font name: DFWaWaTC-W5  (UIFONT要吃這個名字)

儷黑體  檔名:儷黑 Pro.ttf
Family name: LiHei Pro
Font name: LiHeiPro



 

2012年9月12日 星期三

繪圖基本實作(二)

使用自定的中文字型,來畫出中文字的實作

免費字型檔下載區
http://www.wazu.jp/gallery/Fonts_ChineseTraditional.html



1. 新開一個全新的專案

2. 為了繪圖加入一個UIView的Class檔



3. 加入中文字型檔


4. 註冊中文字型檔,需要編輯Plist檔,在Application requires iphone來增加一個選項


5. 增加一個Fonts provided by application
6. 在Fonts provided by application的item0裡面加上中文字型檔BiauKai.ttf (標楷體)

7. 在drawChinese.m加上繪圖所需的程式碼

#import "drawChinese.h"

@implementation drawChinese

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

- (void) drawChineseText1:(NSString *)text x:(float)x y:(float)y {
   
    UIFont *font = [UIFont fontWithName:@"BiauKai" size:20];
    [text drawAtPoint:CGPointMake(x, y) withFont:font];
}

- (void) drawChineseText2:(NSString *)text x:(float)x y:(float)y {
   
    UIFont *font = [UIFont fontWithName:@"Arial" size:20];
   
    [text drawAtPoint:CGPointMake(x, y) withFont:font];
}


- (void)drawTestText:(CGContextRef) context
{
    CGContextSetFillColorWithColor(context, [UIColor blueColor].CGColor);
    NSString *text = @"蘋";
    [self drawChineseText1:text x:50 y:100];
    text = @"果";
    [self drawChineseText1:text x:50 y:130];
   
    text = @"蘋";
    [self drawChineseText2:text x:100 y:100];
    text = @"果";
    [self drawChineseText2:text x:100 y:130];
   
    CGContextStrokePath(context);
}

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
   
    [self drawTestText:context];
       
}

8. 在showChineseViewController.h加入drawChinese.h

#import <UIKit/UIKit.h>
#import "drawChinese.h"

@interface showChineseViewController : UIViewController

@end






9. 在showChineseViewController.m加上drawChinese的instance
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
   
    drawChinese *drawText = [[drawChinese alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:drawText];
   
    drawText.backgroundColor = [UIColor whiteColor];
   
}




10. 完成後顯示字型,左邊是標楷體,右邊是系統中文字

2012年9月11日 星期二

繪圖基本實作(一)

實作一個畫圓的繪圖功能
Xcode版本4.4.1

細節說明請看 UIView說明 http://kirenenko-tw.blogspot.tw/2012/06/uiview.html

1. 先開一個專案,同樣用Single View Application的 Template

2. 新增一個draw的Class,繼承自UIView


   

3. 先針對draw.m修改,增加畫圓的程式碼

- (void)drawCircleAtPoint:(CGPoint)p withRadius:(CGFloat)radius inContext:(CGContextRef)context
{
    UIGraphicsPushContext(context);
    CGContextBeginPath(context);
    CGContextAddArc(context, p.x, p.y, radius, 0, 2*M_PI, YES); // 360 degree (0 to 2pi) arc
    CGContextStrokePath(context);
    UIGraphicsPopContext();
}

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
   
    CGPoint midPoint; // center of our bounds in our coordinate system
    midPoint.x = self.bounds.origin.x + self.bounds.size.width/2;
    midPoint.y = self.bounds.origin.y + self.bounds.size.height/2;
   
    CGFloat size = self.bounds.size.width / 2;
    if (self.bounds.size.height < self.bounds.size.width) 
         size = self.bounds.size.height / 2;
    ///size *= self.scale; // scale is percentage of full view size
   
    CGContextSetLineWidth(context, 5.0);
    [[UIColor blueColor] setStroke];
   
    [self drawCircleAtPoint:midPoint withRadius:size inContext:context]; // head
   
}


4. 修改drawViewController.h

#import <UIKit/UIKit.h>
#import "draw.h"  // 加入 class draw到ViewController

@interface drawViewController : UIViewController

@end

5. 修改drawViewController.m
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
   
    //增加畫圓形的instance到ViewController
    draw *drawCircle = [[draw alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:drawCircle];
   
    // 設定背景為白色。
    drawCircle.backgroundColor = [UIColor whiteColor];
   
}


6. 執行後結果如下