- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{
//如果touch到closeButton的區域,就觸發closeButton
CGPoint pt = [[touches anyObject]locationInView:self.view];
if (pt.x>closeButton.frame.origin.x &&
pt.x<closeButton.frame.origin.x+closeButton.frame.size.width &&
pt.y>closeButton.frame.origin.y &&
pt.y<closeButton.frame.origin.y+closeButton.frame.size.height)
{
[self closeButtonTapped:touches];
}
}
2013年6月26日 星期三
2013年6月24日 星期一
2013年6月18日 星期二
objective C 也有 try catch方法
NSString *test = @"test";
unichar a;
int index = 5;
@try {
a = [test characterAtIndex:index];
}
@catch (NSException *exception) {
NSLog(@"%@", exception.reason);
}
@finally {
NSLog(@"Char at index %d cannot be found", index);
NSLog(@"Max index is: %d", [test length]-1);
}
Log:[__NSCFConstantString characterAtIndex:]: Range or index out of bounds
Char at index 5 cannot be found
Max index is: 3
C++ assert()的意思
assert 的用法
可用來除錯。
用法很簡單。沒有回傳值,只要 assert() 括號內的值是 false 就直接結束程式,並印出是哪一行、什麼情況下跳出的。
使用前需 include assert.h。
可用來除錯。
用法很簡單。沒有回傳值,只要 assert() 括號內的值是 false 就直接結束程式,並印出是哪一行、什麼情況下跳出的。
使用前需 include assert.h。
多UIView間touch事件傳值
原本是用一個delegate去選擇touch要停留在那一個UIView回應,
後來發現下面這個方式更好,你可以隨意選擇你要按那一個UIView甚至可以同時觸發二個以上!
把要touch事件trigger寫在UIViewController中,如下面三個function,
然後把要觸發的UIView都加到這個UIViewController中,用下列方式呼叫,
這樣的好處是也可以對父類別的touch事件做呼叫
// Pass touches on to the AR view (EAGLView)
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
// pass events down to parent ViewController
// super是用來呼叫父類別的方法
[super touchesBegan:touches withEvent:event];
// 對自己view做匯入,之後以自己收到的touch去呼叫view的touch事件
[arViewController.arView touchesBegan:touches withEvent:event];
}
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
[arViewController.arView touchesEnded:touches withEvent:event];
}
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
// Implemented only to prevent the super class methods from executing
}
// 在使用這個方式前,記得在其他view加入下面指令,以確保touch事件都能直接觸到parientViewController
self.userInteractionEnabled = NO;
後來發現下面這個方式更好,你可以隨意選擇你要按那一個UIView甚至可以同時觸發二個以上!
把要touch事件trigger寫在UIViewController中,如下面三個function,
然後把要觸發的UIView都加到這個UIViewController中,用下列方式呼叫,
這樣的好處是也可以對父類別的touch事件做呼叫
// Pass touches on to the AR view (EAGLView)
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
// pass events down to parent ViewController
// super是用來呼叫父類別的方法
[super touchesBegan:touches withEvent:event];
// 對自己view做匯入,之後以自己收到的touch去呼叫view的touch事件
[arViewController.arView touchesBegan:touches withEvent:event];
}
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
[arViewController.arView touchesEnded:touches withEvent:event];
}
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
// Implemented only to prevent the super class methods from executing
}
// 在使用這個方式前,記得在其他view加入下面指令,以確保touch事件都能直接觸到parientViewController
self.userInteractionEnabled = NO;
2013年6月17日 星期一
2013年6月13日 星期四
在xcode把沒有git的專案加入git
一,先把專案丟到桌面
二,用xcode在你原本放專案的地方建立一個同名的新專案,記得把create repository打勾
三,關掉xcode
四,刪除新專案資料匣的所有檔案
五,把桌面上你原來專案的檔案拉到新建立同名專案的資料夾中
六,點二下開始專案,就可以看到GIT已經存在了
七,去commit一個新initial commit,因為原來的initial commit是剛剛那個空專案
八,have fun!!
二,用xcode在你原本放專案的地方建立一個同名的新專案,記得把create repository打勾
三,關掉xcode
四,刪除新專案資料匣的所有檔案
五,把桌面上你原來專案的檔案拉到新建立同名專案的資料夾中
六,點二下開始專案,就可以看到GIT已經存在了
七,去commit一個新initial commit,因為原來的initial commit是剛剛那個空專案
八,have fun!!
2013年6月10日 星期一
在objective-C宣告singleton
在YourClass中加入下列的初始化方法
status YourClass* singleton;
+ ( YourClass* ) initWithSingleton{
@synchronized( self ){
if ( ! singleton )
singleton = [ [ YourClass alloc ] init ];
}
return singleton;
}
這邊的重點有四個
第一:以+宣告Class method,讓我們可以在實例被宣告之前就可以呼叫這個method。
第二:以status將singleton宣告為靜態實例。
第三:合成實例時,對getter做手腳,如果實例已經存在,則不宣告新的實例,直接return已存在的。
第四:用@synchronized()來控制不會被其他執行緒存取
另一種
+(BooksManager *)sharedInstance
{
@synchronized(self)
{
if (sharedInstance == nil)
{
sharedInstance = [[self alloc] init];
}
}
return sharedInstance;
}
status YourClass* singleton;
+ ( YourClass* ) initWithSingleton{
@synchronized( self ){
if ( ! singleton )
singleton = [ [ YourClass alloc ] init ];
}
return singleton;
}
這邊的重點有四個
第一:以+宣告Class method,讓我們可以在實例被宣告之前就可以呼叫這個method。
第二:以status將singleton宣告為靜態實例。
第三:合成實例時,對getter做手腳,如果實例已經存在,則不宣告新的實例,直接return已存在的。
第四:用@synchronized()來控制不會被其他執行緒存取
另一種
+(BooksManager *)sharedInstance
{
@synchronized(self)
{
if (sharedInstance == nil)
{
sharedInstance = [[self alloc] init];
}
}
return sharedInstance;
}
下載影片
// 大影片(35 MB)
#define LARGE_URL @"http://www.archive.org/download/BettyBoopCartoons/Betty_Boop_More_Pep_1936_512kb.mp4"
// 小影片(3 MB)
#define SMALL_URL @"http://www.archive.org/download/Drive-inSaveFreeTv/Drive-in--SaveFreeTv_512kb.mp4"
// 無效的影片網址
#define FAKE_URL @"http://www.idontbelievethisisavalidurlforthisexample.com"
#define DEST_PATH [NSHomeDirectory() stringByAppendingString:@"/Documents/Movie.mp4"]
// 選擇下載哪個項目
NSArray *items = [NSArray arrayWithObjects: SMALL_URL, LARGE_URL, FAKE_URL, nil];
NSString *whichItem = [items objectAtIndex:seg.selectedSegmentIndex];
NSURL *sourceURL = [NSURL URLWithString:whichItem];
// 移除任何已存在的資料
if ([[NSFileManager defaultManager] fileExistsAtPath:DEST_PATH])
[[NSFileManager defaultManager] removeItemAtPath:DEST_PATH error:nil];
// 啟動網路活動指示器
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
// 在新的NSOperationQueue裡進行下載
[[[NSOperationQueue alloc] init] addOperationWithBlock:
^{
[self getData:sourceURL];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// 在主緒程裡處理收尾工作
[self downloadFinished];
}];
}];
#define LARGE_URL @"http://www.archive.org/download/BettyBoopCartoons/Betty_Boop_More_Pep_1936_512kb.mp4"
// 小影片(3 MB)
#define SMALL_URL @"http://www.archive.org/download/Drive-inSaveFreeTv/Drive-in--SaveFreeTv_512kb.mp4"
// 無效的影片網址
#define FAKE_URL @"http://www.idontbelievethisisavalidurlforthisexample.com"
#define DEST_PATH [NSHomeDirectory() stringByAppendingString:@"/Documents/Movie.mp4"]
// 選擇下載哪個項目
NSArray *items = [NSArray arrayWithObjects: SMALL_URL, LARGE_URL, FAKE_URL, nil];
NSString *whichItem = [items objectAtIndex:seg.selectedSegmentIndex];
NSURL *sourceURL = [NSURL URLWithString:whichItem];
// 移除任何已存在的資料
if ([[NSFileManager defaultManager] fileExistsAtPath:DEST_PATH])
[[NSFileManager defaultManager] removeItemAtPath:DEST_PATH error:nil];
// 啟動網路活動指示器
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
// 在新的NSOperationQueue裡進行下載
[[[NSOperationQueue alloc] init] addOperationWithBlock:
^{
[self getData:sourceURL];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// 在主緒程裡處理收尾工作
[self downloadFinished];
}];
}];
iOS App沙箱路徑
//用來得到App的存放目錄的路徑,在該目錄下有三個folder:一、Documents,二、Library,三、Temp,除此之外還有一個編譯完程式碼.app檔。
//這個目錄就是app的sandbox,代表這個iOS App只能存取這個目錄的範圍。
NSString *path = NSHomeDirectory();
//沙箱中的路徑
NSString *moviePath = [NSHomeDirectory() stringByAppendingString:@"/Documents/Movie.mp4"];
//公司測試機的沙箱路徑
/var/mobile/Applications/DEA6AF92-2D7C-435D-A318-XXXXXXXXXXXX/Documents/Movie.mp4
//這個目錄就是app的sandbox,代表這個iOS App只能存取這個目錄的範圍。
NSString *path = NSHomeDirectory();
//沙箱中的路徑
NSString *moviePath = [NSHomeDirectory() stringByAppendingString:@"/Documents/Movie.mp4"];
//公司測試機的沙箱路徑
/var/mobile/Applications/DEA6AF92-2D7C-435D-A318-XXXXXXXXXXXX/Documents/Movie.mp4
iPhone的檔案系統
因為安全性的因素,在iPhone OS下,每一個軟體的檔案以及資料夾都是被獨立隔開的,而每一個軟體可以讀取、寫入的檔案系統,大概可以用下列的結構顯示:- <程式根目錄>
- 我的程式.app (程式的主要資料夾,只能讀取)
- 我的程式
- MainWindow.xib
- 其他在Xcode中所加入的Resources
- Documents
- Library
- Cache
- Preference
- 我的程式.app (程式的主要資料夾,只能讀取)
// 基本的目錄 NSString *homePath = NSHomeDirectory(); // 根目錄 NSString *tmpPath = NSTemporaryDirectory(); // 暫存目錄 // Documents 資料夾 NSArray *paths = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsPath = [paths objectAtIndex:0]; // <程式根目錄>/Documents/foo.plist NSString *fooPath = [documentsPath stringByAppendingPathComponent:@“foo.plist”];
2013年6月7日 星期五
跨執行緒存取UIKit會crash的解法
//把你要執行的程式包在 dispatch_async( dispatch_get_main_queue(), ^{......});裡面, 以主執行緒去執行。
dispatch_async( dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:@"presentOfficialWebview" object:nil];
});
dispatch_async( dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:@"presentOfficialWebview" object:nil];
});
2013年6月5日 星期三
實機測試時出現Could not change executable permissions on the application
因為iPhone上已經存在相同bundle ID的App,
將iPhone上原來的App刪除,或是改掉現在的bundle ID就可以成功。
將iPhone上原來的App刪除,或是改掉現在的bundle ID就可以成功。
2013年6月3日 星期一
在高通openGL中take a screenshot
- (BOOL)presentFramebuffer
{
if (takePhoto)
{
[self glToUIImage];
takePhoto = NO;
}
....remaining code ...
}
- (UIImage*) glToUIImage
{
GLint backingWidth, backingHeight;
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
CGRect s = CGRectMake(0, 0, backingWidth, backingHeight);
uint8_t *buffer = (uint8_t *) malloc(s.size.width * s.size.height * 4);
glReadPixels(0, 0, s.size.width, s.size.height, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, buffer, s.size.width * s.size.height * 4, NULL);
CGImageRef iref = CGImageCreate(s.size.width, s.size.height, 8, 32, s.size.width * 4, CGColorSpaceCreateDeviceRGB(),
kCGBitmapByteOrderDefault, ref, NULL, true, kCGRenderingIntentDefault);
size_t width = CGImageGetWidth(iref);
size_t height = CGImageGetHeight(iref);
size_t length = width * height * 4;
uint32_t *pixels = (uint32_t *)malloc(length);
CGContextRef cgcontext = CGBitmapContextCreate(pixels, width, height, 8, width * 4,
CGImageGetColorSpace(iref), kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Big);
CGAffineTransform transform = CGAffineTransformIdentity;
transform = CGAffineTransformMakeTranslation(0.0f, height);
transform = CGAffineTransformScale(transform, 1.0, -1.0);
CGContextConcatCTM(cgcontext, transform);
CGContextDrawImage(cgcontext, CGRectMake(0.0f, 0.0f, width, height), iref);
CGImageRef outputRef = CGBitmapContextCreateImage(cgcontext);
UIImage* outputImage = [UIImage imageWithCGImage:outputRef];
UIImageWriteToSavedPhotosAlbum(outputImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
CGDataProviderRelease(ref);
CGImageRelease(iref);
CGContextRelease(cgcontext);
CGImageRelease(outputRef);
free(pixels);
free(buffer);
NSLog(@"Screenshot size: %d, %d", (int)[outputImage size].width, (int)[outputImage size].height);
return outputImage;
}
// callback for UIImageWriteToSavedPhotosAlbum
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
if (error) {
NSLog(@"Photo save error");
}
else {
NSLog(@"Photo saved");
}
}
訂閱:
文章 (Atom)