您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關IOS開發有用的小知識點有哪些的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
1、獲取系統語言設置
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSArray *languages = [userDefault objectForKey:@"AppleLanguages"];
NSString *preferredLang = [languages objectAtIndex:0];
2、緩存路徑下文件大小
- (unsigned long long int) cacheFolderSize
{
NSFileManager *_manager = [NSFileManager defaultManager];
NSArray *_cachePaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,
NSUserDomainMask, YES);
NSString *_cacheDirectory = [_cachePaths objectAtIndex:];
NSArray *_cacheFileList;
NSEnumerator *_cacheEnumerator;
NSString *_cacheFilePath;
unsigned long long int _cacheFolderSize = ;
_cacheFileList = [ _manager subpathsAtPath:_cacheDirectory];
_cacheEnumerator = [_cacheFileList objectEnumerator];
while (_cacheFilePath = [_cacheEnumerator nextObject])
{
NSDictionary *_cacheFileAttributes = [_managerfileAttributesAtPath:
[_cacheDirectory stringByAppendingPathComponent:_cacheFilePath]
traverseLink:YES];
_cacheFolderSize += [_cacheFileAttributes fileSize];
}
// 單位是字節
return _cacheFolderSize;
}
3、Popover push 時 Frame無法改變解決辦法
在popover中的ViewController中實現:
- (void)viewWillAppear:(BOOL)animated
{
CGSize size = CGSizeMake(320, 480); // size of view in popover
self.contentSizeForViewInPopover = size;
[super viewWillAppear:animated];
}
4、tableview滑動導致NSTimer和委托回調停止解決辦法
/ /請求回調
NSURLRequest * 請求 = ...
scheduleInRunLoop :[ NSRunLoop currentRunLoop ]
forMode :NSRunLoopCommonModes ]
[ 連接開始] / /定時器回調
NSTimer * updateTimer = [NSTimer scheduledTimerWithTimeInterval:0.01f目標:自我選擇:選擇(updatePencent)的UserInfo:無重復:是];
* NSRunLoop主要= [NSRunLoop currentRunLoop]
[主要addTimer:updateTimer forMode:NSRunLoopCommonModes];
5、手勢識別類
UIGestureRecognizer
6、SFHFKeychainUtils 存儲信息
蘋果SDK自帶的就有密碼保護,使用方法很簡單,如下:
1、引入Security.frameWork框架。
2、引入頭文件:SFHKeychainUtils.h.
3、存密碼:
[SFHFKeychainUtils storeUsername:@"dd" andPassword:@"aa"forServiceName:SERVICE_NAMEupdateExisting:1 error:nil];
[SFHFKeychainUtils deleteItemForUsername:@"dd" andServiceName:SERVICE_NAME error:nil];
4、取密碼:
NSString *passWord = [SFHFKeychainUtils getPasswordForUsername:@"dd"andServiceName:SERVICE_NAMEerror:nil];
7、missing required architecture i386 in file 解決辦法
在TargetInfo里面修改 Framework Search Pasths 刪除里面內容就可以了。
8、view 放大縮小動畫效果
//創建縮小了的視圖
myWeiBoImageVC = [[UIViewController alloc] init];
myWeiBoImageVC.view.clipsToBounds = YES;
myWeiBoImageVC.view.alpha = 0.0;
myWeiBoImageVC.view.frame = CGRectMake(64, 0, 1024-64, 768-20);
[self.view addSubview:myWeiBoImageVC.view];
CGAffineTransform newTransform =
CGAffineTransformScale(myWeiBoImageVC.view.transform, 0.1, 0.1);
[myWeiBoImageVC.view setTransform:newTransform];
myWeiBoImageVC.view.center = CGPointMake(670, 100);
[self performSelector:@selector(p_w_picpathViewControllerBigAnimation)];
//放大剛剛創建縮小后的視圖
- (void)p_w_picpathViewControllerBigAnimation{
[UIView beginAnimations:@"p_w_picpathViewBig" context:nil];
[UIView setAnimationDuration:0.5];
CGAffineTransform newTransform = CGAffineTransformConcat(myWeiBoImageVC.view.transform, CGAffineTransformInvert(myWeiBoImageVC.view.transform));
[myWeiBoImageVC.view setTransform:newTransform];
myWeiBoImageVC.view.alpha = 1.0;
myWeiBoImageVC.view.center = CGPointMake(416, 510);
[UIView commitAnimations];
}
//縮小視圖 隱藏
- (void)p_w_picpathViewControllerSmallAnimation{
[UIView beginAnimations:@"p_w_picpathViewSmall" context:nil];
[UIView setAnimationDuration:0.5];
CGAffineTransform newTransform = CGAffineTransformScale(myWeiBoImageVC.view.transform, 0.1, 0.1);
[myWeiBoImageVC.view setTransform:newTransform];
myWeiBoImageVC.view.center = CGPointMake(670, 100);
[UIView commitAnimations];
}
9、UIScrollView 控制View縮放
allImageScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 768, 1024)];
allImageScrollView.minimumZoomScale = 0.3;
allImageScrollView.maximumZoomScale = 1.0;
allImageScrollView.backgroundColor = [UIColor clearColor];
allImageScrollView.delegate = self;
[self.view addSubview:allImageScrollView];
mPicStatusesViewController = [[PicStatusesViewController alloc] init];
[allImageScrollView addSubview:mPicStatusesViewController.view];
//UIScrollView Delegete 實現
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return mPicStatusesViewController.view; //返回ScrollView上添加的需要縮放的視圖
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
//縮放操作中被調用
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
{
//縮放結束后被調用
}
10、iOS3.2 播放視頻
NSString *urlString = [NSString stringWithString:@"視頻url"];
NSURL *movieUrl = [[NSURL alloc] initWithString:urlString];
MPMoviePlayerController *myMoviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:movieUrl];
myMoviePlayer.view.frame = CGRectMake(250, 250, 350, 350);
[self.view addSubview:myMoviePlayer.view];
myMoviePlayer.shouldAutoplay = YES;
myMoviePlayer.scalingMode= MPMovieScalingModeAspectFit;
[myMoviePlayer play];
11、谷歌地圖翻起動畫效果
CATransition *animation = [CATransition animation];
[animation setDelegate:self];
[animation setDuration:0.35];
[animation setTimingFunction:UIViewAnimationCurveEaseInOut];
if (!curled){
animation.type = @"pageCurl";
animation.fillMode = kCAFillModeForwards;
animation.endProgress = 0.40;
} else {
animation.type = @"pageUnCurl";
animation.fillMode = kCAFillModeBackwards;
animation.startProgress = 0.30;
}
[animation setRemovedOnCompletion:NO];
[self.view exchangeSubviewAtIndex:0 withSubviewAtIndex:1];
[self.view.layer addAnimation:animation forKey:@"pageCurlAnimation"];
12、給View添加陰影 和邊框
UIImageView *imgvPhoto = [UIImageView alloc] init];
//添加邊框
CALayer *layer = [_imgvPhoto layer];
layer.borderColor = [[UIColor whiteColor] CGColor];
layer.borderWidth = 5.0f;
//添加四個邊陰影
_imgvPhoto.layer.shadowColor = [UIColor blackColor].CGColor;
_imgvPhoto.layer.shadowOffset = CGSizeMake(0, 0);
_imgvPhoto.layer.shadowOpacity = 0.5;
_imgvPhoto.layer.shadowRadius = 10.0;
//添加兩個邊陰影
_imgvPhoto.layer.shadowColor = [UIColor blackColor].CGColor;
_imgvPhoto.layer.shadowOffset = CGSizeMake(4, 4);
_imgvPhoto.layer.shadowOpacity = 0.5;
_imgvPhoto.layer.shadowRadius = 2.0;
13、使用NSTimer與UIView動畫實現飄雪效果
viewDidLoad事件中,增加一個圖片及定時器并啟動,這里的pic請在頭文件中定義。
-(void)viewDidLoad{
[super viewDidLoad];
self.pic = [UIImage p_w_picpathNamed:@"snow.png"];//初始化圖片
//啟動定時器,實現飄雪效果
[NSTimer scheduledTimerWithTimeInterval:(0.2) target:self selector:@selector(ontime) userInfo:nil repeats:YES];
}
然后再實現定時器定時調用的ontime方法:
-(void)ontime{
UIImageView *view = [[UIImageView alloc] initWithImage:pic];//聲明一個UIImageView對象,用來添加圖片
view.alpha = 0.5;//設置該view的alpha為0.5,半透明的
int x = round(random()20);//隨機得到該圖片的x坐標
int y = round(random()20);//這個是該圖片移動的最后坐標x軸的
int s = round(random())+10;//這個是定義雪花圖片的大小
int sp = 1/round(random()0)+1;//這個是速度
view.frame = CGRectMake(x, -50, s, s);//雪花開始的大小和位置
[self.view addSubview:view];//添加該view
[UIView beginAnimations:nil context:view];//開始動畫
[UIView setAnimationDuration:10*sp];//設定速度
view.frame = CGRectMake(y, 500, s, s);//設定該雪花最后的消失坐標
[UIView setAnimationDelegate:self];
[UIView commitAnimations];
}
14、配置Xcode 看程序崩潰信息
1、在xcode中的左側目錄中找到Executables 打開
2、雙擊和工程名一樣的文件。
3、在打開的文件中的Arguments選項,在下面的框中加入Name: NSZombieEnabled 設置value為YES。
15、程序中發送郵件和檢測設備郵箱是否被配置
-(void)addEmail{
Class mailClass = (NSClassFromString(@"MFMailComposeViewController"));
if (mailClass != nil){
if ([mailClass canSendMail]){
[self displayComposerSheet];
}else{
[self launchMailAppOnDevice];
}
}else{
[self launchMailAppOnDevice];
}
}
-(void)displayComposerSheet
{
MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
controller.navigationBar.tag = 1002;
[self.navigationController.navigationBar setNeedsDisplay];
controller.mailComposeDelegate = self;
[controller setSubject:@"意見反饋"];
[controller setToRecipients:[[NSArray alloc] initWithObjects:@"555@cifco.net.cn",nil]];
NSString *emailBody = nil;
[controller setMessageBody:emailBody isHTML:YES];
[self presentModalViewController:controller animated:YES];
[controller release];
}
#pragma mark mailComposeDelegate ----
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
if (result == MFMailComposeResultSent)
{
[self dismissModalViewControllerAnimated:YES];
}
if (result == MFMailComposeResultSaved)
{
[self dismissModalViewControllerAnimated:YES];
}
if (result == MFMailComposeResultFailed)
{
Emailalert = [[UIAlertView alloc] initWithTitle:@"" message:@"發送失敗" delegate:selfcancelButtonTitle:@"知道了" otherButtonTitles:nil];
[Emailalert show];
}
if (result == MFMailComposeResultCancelled)
{
[self dismissModalViewControllerAnimated:YES];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(alertView == Emailalert)
{
if (buttonIndex == )
{
[self dismissModalViewControllerAnimated:YES];
}
}else
{
if (buttonIndex == )
{
//[self dismissModalViewControllerAnimated:YES];
}else
{
NSString *recipients = @"mailto:theonelgq@gmail.com?cc=theone_liuguoqing@163.com&subject=text";
NSString *body = @"&body=text!";
NSString *email = [NSString stringWithFormat:@"%@%@", recipients, body];
email = [email stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:email]];
}
}
}
#pragma mark -
#pragma mark Workaround
-(void)launchMailAppOnDevice
{
isEmailalert = [[UIAlertView alloc] initWithTitle:@"警告" message:@"請配置您的郵箱" delegate:selfcancelButtonTitle:@"取消" otherButtonTitles:@"好的",nil];
[isEmailalert show];
}
16、程序啟動畫面大小
iOS設備現在有三種不同的分辨率:iPhone 320x480、iPhone 4 640x960、iPad 768x1024。以前程序的啟動畫面(圖片)只要準備一個 Default.png 就可以了,但是現在變得復雜多了。下面就是 CocoaChina 會員做得總結
如果一個程序,既支持iPhone又支持iPad,那么它需要包含下面幾個圖片:
Default-Portrait.png iPad專用豎向啟動畫面 768x1024或者768x1004
Default-Landscape.png iPad專用橫向啟動畫面 1024x768或者1024x748
Default-PortraitUpsideDown.png iPad專用豎向啟動畫面(Home按鈕在屏幕上面),可省略 768x1024或者768x1004
Default-LandscapeLeft.png iPad專用橫向啟動畫面,可省略 1024x768或者1024x748
Default-LandscapeRight.png iPad專用橫向啟動畫面,可省略 1024x768或者1024x748
Default.png iPhone默認啟動圖片,如果沒有提供上面幾個iPad專用啟動圖片,則在iPad上運行時也使用Default.png(不推薦) 320x480或者320x460
Default@2x.png iPhone4啟動圖片640x960或者640x920
為了在iPad上使用上述的啟動畫面,你還需要在info.plist中加入key: UISupportedInterfaceOrientations。同時,加入值UIInterfaceOrientationPortrait, UIInterfacOrientationPortraitUpsideDown, UIInterfaceOrientationLandscapeLeft, UIInterfaceOrientationLandscapeRight
17、ASIHTTPRequest實現斷點下載
- (IBAction)URLFetchWithProgress:(id)sender
{
[startButton setTitle:@"Stop" forState:UIControlStateNormal];
[startButton addTarget:self action:@selector(stopURLFetchWithProgress:)forControlEvents:UIControlEventTouchUpInside];
NSString*tempFile = [[[[NSBundle mainBundle] bundlePath]stringByDeletingLastPathComponent]stringByAppendingPathComponent:@"MemexTrails_1.0b1.zip.download"];
if ([[NSFileManager defaultManager] fileExistsAtPath:tempFile]) {
[[NSFileManager defaultManager] removeItemAtPath:tempFile error:nil];
}
[self resumeURLFetchWithProgress:self];
}
- (IBAction)stopURLFetchWithProgress:(id)sender
{
networkQueue = [[ASINetworkQueue alloc] init];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:selfselector:@selector(updateBandwidthUsageIndicator) userInfo:nil repeats:YES];
timer = nil;
[startButton setTitle:@"Stop" forState:UIControlStateNormal];
[startButton addTarget:self action:@selector(URLFetchWithProgress:)forControlEvents:UIControlEventTouchUpInside];
[networkQueue cancelAllOperations];
[resumeButton setEnabled:YES];
}
- (IBAction)resumeURLFetchWithProgress:(id)sender
{
[resumeButton setEnabled:NO];
[startButton setTitle:@"Start" forState:UIControlStateNormal];
[startButton addTarget:self action:@selector(stopURLFetchWithProgress:)forControlEvents:UIControlEventTouchUpInside];
[networkQueue cancelAllOperations];
[networkQueue setShowAccurateProgress:YES];
[networkQueue setDownloadProgressDelegate:progressIndicator];
[networkQueue setDelegate:self];
[networkQueue setRequestDidFinishSelector:@selector(URLFetchWithProgressComplete:)];
ASIHTTPRequest*request=[[[ASIHTTPRequest alloc] initWithURL:[NSURLURLWithString:@"http://9991.net/blog/mp3/2.mp3"]] autorelease];
[request setDownloadDestinationPath:[[[[NSBundle mainBundle] bundlePath]
stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"MemexTrails_1.0b1.mp3"]];
[request setTemporaryFileDownloadPath:[[[[NSBundle mainBundle] bundlePath]stringByDeletingLastPathComponent]stringByAppendingPathComponent:@"MemexTrails_1.0b1.zip.down"]];
[request setAllowResumeForFileDownloads:YES];
[networkQueue addOperation:request];
[networkQueue go];
}
- (void)URLFetchWithProgressComplete:(ASIHTTPRequest *)request
{
if ([request error]) {
fileLocation.text=[NSString stringWithFormat:@"An error occurred:%@",[[[requesterror] userInfo] objectForKey:@"Title"]];
} else {
fileLocation.text=[NSString stringWithFormat:@"File downloaded to %@",[requestdownloadDestinationPath]];
}
[startButton setTitle:@"Start" forState:UIControlStateNormal];
[startButton addTarget:self action:@selector(URLFetchWithProgress:)forControlEvents:UIControlEventTouchUpInside];
}
- (IBAction)throttleBandwidth:(id)sender
{
if ([(UIButton *)sender state] ==YES) {
[ASIHTTPRequest setMaxBandwidthPerSecond:ASIWWANBandwidthThrottleAmount];
} else {
[ASIHTTPRequest setMaxBandwidthPerSecond:];
}
}
18、Safari 啟動本地app
在plist文件中加入URL types 結構如下圖,在Safari中地址欄輸入 設置的字符串,比如設置的是
QQ,地址欄輸入 QQ:// 就可以起點本地應用。
19、拖到視頻進度與滑動手勢沖突解決辦法
#pragma mark -
#pragma mark UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
UIView *touchView = touch.view;
if ([touchView isKindOfClass:[UISlider class]])
{
return NO;
}
else
{
return YES;
}
}
20、創建并保存Cookie的方法
NSString *cookieString = [NSString stringWithString:[headers objectForKey:@"Cookie"]];
NSMutableDictionary *cookieProperties = [[NSMutableDictionary alloc] init];
[cookieProperties setValue:cookieString forKey:NSHTTPCookieValue];
[cookieProperties setValue:@"QQCookie" forKey:NSHTTPCookieName];
[cookieProperties setValue:@".QQ.com" forKey:NSHTTPCookieDomain];
[cookieProperties setValue:[NSDate dateWithTimeIntervalSinceNow:60*60] forKey:NSHTTPCookieExpires];
[cookieProperties setValue:@"/" forKey:NSHTTPCookiePath];
NSHTTPCookie *newcookie = [[NSHTTPCookie alloc] initWithProperties:cookieProperties];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:newcookie];
21、popover橫豎屏位置改變解決辦法
1、 delegate中 處理
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
userImageShow = NO;
if ([popoverController isEqual:myPopover])
{
[myPopover release];
myPopover = nil;
}
}
2、屏幕旋轉時重新彈出Popover
if (myPopover)
{
if ((self.interfaceOrientation ==
UIInterfaceOrientationLandscapeLeft) || (self.interfaceOrientation ==
UIInterfaceOrientationLandscapeRight))
{
[myPopover presentPopoverFromRect:CGRectMake(10,180, 1, 1)
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionRight
animated:YES];
}
else
{
[myPopover presentPopoverFromRect:CGRectMake(20,180, 1, 1)
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionRight
animated:YES];
}
}
22、plist各種key值含義
原文:http://www.minroad.com/?p=434
UIRequiresPersistentWiFi 在程序中彈出wifi選擇的key(系統設置中需要將wifi提示打開)
UIAppFonts 內嵌字體(https://cache.yisu.com/upload/information/20200311/45/197695.jpg(更名而已)
UIPrerenderedIcon icon上是否有高光
UIRequiredDeviceCapabilities 設備需要的功能(具體點擊這里查看)
UIStatusBarHidden 狀態欄隱藏(和程序內的區別是在于顯示Default.png已經生效)
UIStatusBarStyle 狀態欄類型
UIViewEdgeAntialiasing 是否開啟抗鋸齒
CFBundleDisplayName app顯示名
CFBundleIconFile、CFBundleIconFiles 圖標
CFBundleName 與CFBundleDisplayName的區別在于這個是短名,16字符之內
CFBundleVersion 版本
CFBundleURLTypes 自定義url,用于利用url彈回程序
CFBundleLocalizations 本地資源的本地化語言,用于itunes頁面左下角顯示本地話語種
CFBundleDevelopmentRegion 也是本地化相關,如果用戶所在地沒有相應的語言資源,則用這個key的value來作為默認
最后附上官方文檔,所有的key都有,看英文原版才是正路:)點我進入
24、xcode工程內添加多個Target
轉自:http://blog.sina.com.cn/s/blog_682dc7810100pv8t.html
啥叫多Targets, 有啥用!
相信很多人都注意到XCode中,
有個Target的概念.
這在很多地方都有所體現,
比如打開一個工程后, 左側的列表中有Targets一項, 而在工程界面的頂部菜單中,
project里面也有多個涉及到Target的項目,
那么這個Target到底是什么呢?
Apple的人是這樣說的:
引用
Targets that define the products to build. A
target organizes the files and instructions needed to build a
product into a sequence of build actions that can be taken.
簡單的理解的話,
可以認為一個target對應一個新的product(基于同一份代碼的情況下). 但都一份代碼了, 弄個新product做啥呢?
折騰這個有意思么?
其實這不是單純的瞎折騰,
雖然代碼是同一份, 但編譯設置(比如編譯條件), 以及包含的資源文件卻可以有很大的差別. 于是即使同一份代碼,
產出的product也可能大不相同.
我們來舉幾個典型的應用多Targets的情況吧,
比如完整版和lite版; 比如同一個游戲的20關, 30關, 50關版; 再或者比如同一個游戲換些資源和名字就當新游戲賣的(喂喂,
你在教些什么...)
Targets之間, 什么相同, 什么不同!
既然是利用同一份代碼產出不同的product,
那么到底不同Target之間存在著什么樣的差異呢?
要解釋這個問題,
我們就要來看看一個Target指定了哪些內容.
從XCode左側的列表中,
我們可以看到一個Target包含了Copy Bundle Resources, Compile Sources, Link
Binary With Libraries. 其中
Copy
Bundle Resources 是指生成的product的.app內將包含哪些資源文件
Compile
Sources 是指將有哪些源代碼被編譯
Link
Binary With Libraries 是指編譯過程中會引用哪些庫文件
通過Copy
Bundle Resources中內容的不同設置, 我們可以讓不同的product包含不同的資源, 包括程序的主圖標等,
而不是把XCode的工程中列出的資源一股腦的包含進去.
而這還不是一個target所指定的全部內容.
每個target可以使用一個獨立,
不同的Info.plist文件.
我們都知道,
這個Info.plist文件內定義了一個iPhone項目的很多關鍵性內容, 比如程序名稱,
最終生成product的全局唯一id等等.
而且不同的target還可以定義完整的差異化的編譯設置,
從簡單的調整優化選項, 到增加條件編譯所使用的編譯條件, 以至于所使用的base SDK都可以差異化指定.
創建第二個Target!
為什么是第二個?
因為第一個就是創建好工程后的默認Target呀! (廢話這么多, 拖走...)
創建target有多種方法,
我們可以從現有的target上復制出一份, 然后略加改動, 也可以完全新建一個target出來. 但其實說穿了,
兩個方法大同小異
首先我們來看看利用復制的方法創建target
利用復制創建target
我們在XCode左側的列表中,
展開 Targets 項, 在現有的target上, 右鍵選擇 "Duplicate", 或者選中現有target后,
在頂部菜單的Edit內選擇"Duplicate"也可以.
此時我們就得到了一個新的target,
而在Resource里面也會得到一個 xxxx copy.plist. 這個新的target與原有的target是完全一致的,
余下的就是一些差異化的修改, 這個我們后面再說
創建全新的target
類似復制的方法,
我們可以在左側的列表中很多地方按下右鍵菜單, 都可以看到Add中會有"New Target..."一項,
而在工程頂部菜單的Project內, 也可以看到這個"New Target..."的身影.
點擊后,
首先會讓你選擇target的類型, 既然我一直所指的都是程序本身, 那么自然選擇Application了(至于其他的嘛,
有興趣的自己研究吧, 比如我們可以把程序中的部分提取成一個Static Library).
Next后,
會讓你輸入一個新的Target的名字, 而不像復制的方法中, 默認生成 xxxxx copy這樣的target名.
但是這樣生成出的Target幾乎是空的.
Copy Bundle Resources, Compile Sources, Link Binary With
Libraries里面都沒有任何內容. 編譯設置也是完全原始的狀態.
可以通過拖拽內容到這些target的設置中,
以及調整編譯選項來完成Target的配置.
Target中部分內容的修改方法!
其實這段的部分內容,
在非多Targets的工程中也可能會用得到.
由于修改基本都是在工程/編譯設置中完成,
因此沒有特殊情況, 就不再聲明了, 打開target對應的工程/編譯設置的方法可以采用在該target上右鍵, 選擇get
info來做到.
生成的product名稱的修改:
Packing段內的Product Name一項
Info.plist文件名:
Packing段內的Info.plist File一項, 比如復制出來的target覺得那個xxxxx
copy.plist太傻就可以在這里改
條
件編譯: 增加一個User-Defined Setting(Target "xxxx"
Info的build頁的左下角那個齒輪中可以看到這個內容), 在Other C Flag里面填入,
比如要定義一個叫做LITE_VERSION的define值, 我們可以寫上 "-DLITE_VERSION" 或
"-DLITE_VERSION=1". 那么在程序中就可以用
#if
defined(LITE_VERSION)
#else
#endif
這樣的條件編譯來部分差異化代碼了
也許有些朋友記得我在代碼區貼過的檢測破解版的代碼,
其中有一種檢測方法就是看info.plist是文本還是二進制的, 那么我們能否建議一個模擬破解的target,
直接生成文本的info.plist以便測試呢?
當然可以,
在packing段內, 有一項叫"Info.plist Output Encoding", 默認值是Binary,
我們只要選成xml, 那么生成出的product.app內的info.plist就直接是文本樣式的了.
另
外, 向Copy Bundle Resources, Compile Sources, Link Binary With
Libraries內添加/刪除文件, 可以在要改動的文件上, 選擇get info, 并且切換到Target頁,
勾選要引用這個文件的target即可. 比如icon.png可以指定給默認target, 而icon_lite.png指定給lite
verion的target
大致就是如此吧, 懶得抓圖了. 各位將就吧. 想到什么需要補充的, 我會加入
另外
一個英文教程:http://www.codza.com/free-iphone-app-version-from-the-same-xcode-project
25、詳解IOS SDK兼容性引導
轉自: http://mobile.51cto.com/iphone-284052.htm
IOS SDK兼容性引導是本文要介紹的內容,主要是基于IOS SDK基礎的開發介紹說明如何應用于XCode工程的基于IOS SDK開發的技術。來看詳細內容講解。
1、用(weakly linked)弱連接類、方法和函數來支持在不同版本之間的程序運行
2、弱連接整個框架(framework)
3、為不同的IOS SDK選擇不同的編譯條件
4、在代碼中找出過時API的使用
5、確定在運行時操作系統和框架(framework)的版本
一 、在IOS中使用弱連接類
在工程中使用類的弱連接的時候必須確保這些類在運行時的可用性,要不會引起動態連接的錯誤。
在IOS4.2以后的版本都是使用NSObject class的方法來檢測弱連接在運行時態的可用性,這種簡單高效的機制使用了NS_CLASS_AVAILABLE的可用性宏。
檢測最近release的framework還不支持NS_CLASS_AVAILABLE的宏
在支持NS_CLASS_AVAILABLE的宏framework的條件編譯中,可以如下的使用
if ([UIPrintInteractionController class]) {
// Create an instance of the class and use it.
} else {
// Alternate code path to follow when the
// class is not available.
}
如果你在不確保是否已經可以使用類方法的時候你可以使用NSClassFromString 方法來判斷,使用方法如下:
Class cls = NSClassFromString (@"NSRegularExpression");
if (cls) {
// Create an instance of the class and use it.
} else {
// Alternate code path to follow when the
// class is not available.
}
二、在方法,函數和符號中使用弱連接
和使用類的弱連接一樣,在使用它之前要確保方法函數和符號在運行時的可用性,要不在編譯的時候會報錯動態連接錯誤,假設你想使用新版本IOS
SDK的特性但是又想能夠運行在低版本的SDK中,那么就要對早期的版本設置相應的開發target,在Object-c中
instancesRespondToSelector:
方法告訴我們所給的方法是否可用,例如:使用availableCaptureModesForCameraDevice:這個方法(在4.0以后才是可
用的),我們可以這樣使用它。
1、檢查一個Object-c方法的可用性
if ([UIImagePickerController instancesRespondToSelector:
@selector (availableCaptureModesForCameraDevice:)]) {
// Method is available for use.
// Your code can check if video capture is available and,
// if it is, offer that option.
} else {
// Method is not available.
// Alternate code to use only still p_w_picpath capture.
}
判斷一個弱連接的C函數是否可用,只要判斷函數的地址是否返回為NULL,以CGColorCreateGenericCMYK 函數為例,我們可以像以下那樣使用。
2、檢查C方法的可用性
if (CGColorCreateGenericCMYK != NULL) {
CGColorCreateGenericCMYK (0.1,0.5.0.0,1.0,0.1);
} else {
// Function is not available.
// Alternate code to create a color object with earlier technology
}
要檢測一個C方法是否可用,比較明確的為地址是否為NULL或零。你不能使用反運算符(!)來否定一個函數的可用性
檢測一個 external(extern)常量或一個通知的名字應當比較它的地址(address)--而不是符號的名稱, 判斷是否為NULL or nil
三、弱連接整個Framework
比如一個在高版本中才出現的Framework,想在低版本使用他的特性。那你就必須弱連接那個使用的Framework,詳見官方的圖解---(其實就是在添加進去的Framework的 required 改成 optional)
http://developer.apple.com/library/ios/#documentation/DeveloperTools/Conceptual/XcodeProjectManagement/
130-Files_in_Projects/project_files.html#//apple_ref/doc/uid/TP40002666-SW4
四、條件編譯for不同的SDK
如果你不止基于一個IOS SDK編譯,你就可能需要為base
sdk使用條件化,可以使用在Availability.h中的定義。這個.h文件存在于系統的文件夾/usr/include的文件夾下,例如想在
Mac OS X v10.5(而不是IOS)中使用函數 CGColorCreateGenericCMYK
使用預處理指令for條件編譯
#ifdef __MAC_OS_X_VERSION_MAX_ALLOWED
// code only compiled when targeting Mac OS X and not iOS
// note use of 1050 instead of __MAC_10_5
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
if (CGColorCreateGenericCMYK != NULL) {
CGColorCreateGenericCMYK(0.1,0.5.0.0,1.0,0.1);
} else {
#endif
// code to create a color object with earlier technology
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
}
#endif
#endif
}
五、尋找出在程序中使用的以過時的實例
在IOS或Mac
OS中有時候API會過時,但是過時不代表著那些就從Library或framework中刪除,但是在使用的過程中會報出warning,并且在不遠的
將來可能會被Apple從中移除。例如我們在code中使用了過時的函數 HPurge那么就會報出如下
'HPurge' is deprecated (declared at /Users/steve/MyProject/main.c:51)
所以我們應當在工程中查找出如下的警告并且修改。
六、確定操作系統和Framework的版本
在運行時檢查IOS的版本
NSString *osVersion = [[UIDevice currentDevice] systemVersion];
在運行時檢查Mac OS X用Gestalt function 和 系統版本常量
另外,對于許多的Framework你可以在運行時檢查指定Framework的版本。
例如:Application Kit(NSApplication.h)定義了NSAppKitVersionNumber常量---可以用來檢查Application Kit Framework的版本
如
APPKIT_EXTERN double NSAppKitVersionNumber;
#define NSAppKitVersionNumber10_0 577
#define NSAppKitVersionNumber10_1 620
#define NSAppKitVersionNumber10_2 663
#define NSAppKitVersionNumber10_2_3 663.6
#define NSAppKitVersionNumber10_3 743
#define NSAppKitVersionNumber10_3_2 743.14
#define NSAppKitVersionNumber10_3_3 743.2
#define NSAppKitVersionNumber10_3_5 743.24
#define NSAppKitVersionNumber10_3_7 743.33
#define NSAppKitVersionNumber10_3_9 743.36
#define NSAppKitVersionNumber10_4 824
#define NSAppKitVersionNumber10_4_1 824.1
#define NSAppKitVersionNumber10_4_3 824.23
#define NSAppKitVersionNumber10_4_4 824.33
#define NSAppKitVersionNumber10_4_7 824.41
#define NSAppKitVersionNumber10_5 949
#define NSAppKitVersionNumber10_5_2 949.27
#define NSAppKitVersionNumber10_5_3 949.33
所以我們可以像如下使用:
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_0) {
/* On a 10.0.x or earlier system */
} else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_1) {
/* On a 10.1 - 10.1.x system */
} else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_2) {
/* On a 10.2 - 10.2.x system */
} else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_3) {
/* On 10.3 - 10.3.x system */
} else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_4) {
/* On a 10.4 - 10.4.x system */
} else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_5) {
/* On a 10.5 - 10.5.x system */
} else {
/* 10.6 or later system */
}
跟以上一樣在 NSObjCRuntime.h中用定義了NSFoundationVersionNumber全局常量
小結:詳解IOS SDK兼容性引導的內容介紹玩玩了,希望通過本文的學習能對你有所幫助!
原文地址:http://blog.csdn.net/diyagoanyhacker/article/details/6673344
26、NSDate 與 NSString 轉換
1、將字符串 “Fri Nov 11 09:06:27 +0800 2011” 轉換成Date:
NSDateFormatter *format = [[NSDateFormatter alloc] init];
NSLocale *enLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en-US"];
[format setLocale:enLocale];
[enLocale release];
[format setDateFormat:@"EEE MMM dd HH:mm:ss ZZZ yyyy"];
NSDate *dateTime = [format dateFromString:message];
將Date轉換成字符串:
NSDate *date = [NSDate date];
NSString * dateString = [format stringFromDate:date];
//字符串轉換成NSDate 需要設置NSLocale 否則真機上會失敗。
2、獲取當前時間,轉化成字符串
NSDateFormatter * formatter = [[NSDateFormatteralloc]init];
formatter.dateStyle = NSDateFormatterMediumStyle;
formatter.timeStyle = NSDateFormatterMediumStyle;
formatter.locale = [NSLocalecurrentLocale];
self.timeLabel.text = [formatterstringFromDate:[NSDatedate]];
3、獲取月、日、年、時、分、秒
NSDateFormatter *formatter =[[[NSDateFormatteralloc] init] autorelease];
formatter.dateStyle = NSDateFormatterMediumStyle;
formatter.timeStyle = NSDateFormatterMediumStyle;
formatter.locale = [NSLocalecurrentLocale];
NSDate *date = [NSDatedate];
[formatter setTimeStyle:NSDateFormatterMediumStyle];
NSCalendar *calendar = [[[NSCalendaralloc] initWithCalendarIdentifier:NSGregorianCalendar]autorelease];
NSDateComponents *comps = [[[NSDateComponentsalloc] init] autorelease];
NSInteger unitFlags = NSYearCalendarUnit |
NSMonthCalendarUnit |
NSDayCalendarUnit |
NSWeekdayCalendarUnit |
NSHourCalendarUnit |
NSMinuteCalendarUnit |
NSSecondCalendarUnit;
//int week=0;
comps = [calendar components:unitFlags fromDate:date];
int week = [comps weekday];
int year=[comps year];
int month = [comps month];
int day = [comps day];
[formatter setDateStyle:NSDateFormatterMediumStyle];
// //This sets the label with the updated time.
int hour = [comps hour];
int min = [comps minute];
int sec = [comps second];
NSLog(@"day%d",day);
NSLog(@"hour%d",hour);
NSLog(@"min%d",min);
NSLog(@"sec%d",sec);
27、數組中存儲數據查詢
NSMutableDictionary *userDic1 = [NSMutableDictionary dictionaryWithCapacity:10];
NSMutableDictionary *userDic2 = [NSMutableDictionary dictionaryWithCapacity:10];
[userDic1 setValue:@"Li" forKey:@"name"];
[userDic2 setValue:@"Wang" forKey:@"name"];
NSArray *userArray = [NSArray arrayWithObjects:userDic1,userDic2,nil];
NSPredicate *namePredicate = [NSPredicate predicateWithFormat:@"SELF.name contains[cd] %@ ",@"L"];
NSMutableArray *searchArray = [NSMutableArray arrayWithArray:[userArray filteredArrayUsingPredicate:namePredicate]];
NSLog(@"searchArray == %@",searchArray);
28、CoreText 總結
(1) NSAttributedString
NSAttributedString 可以將一段文字中的部分文字設置單獨的字體和顏色。
與UITouch結合可以實現點擊不同文字觸發不同事件的交互功能。
主要方法:
- (void)addAttribute:(NSString *)name value:(id)value range:(NSRange)range;
可以設置某段文字的字體名稱,顏色,下滑線等信息。
- (void)removeAttribute:(NSString *)name range:(NSRange)range;
移除之前設置的字體屬性值。
- (void)addAttributes:(NSDictionary *)attrs range:(NSRange)range;
存儲某段文字包含的信息(包括字體屬性或其它,也可以存儲一些自定義的信息)
- (NSDictionary *)attributesAtIndex:(NSUInteger)location effectiveRange:(NSRangePointer)range;
通過location來獲取某段文字中之前存儲的信息NSDictionary
//設置字體
CTFontRef aFont = CTFontCreateWithName((CFStringRef)textFont.fontName, textFont.pointSize, NULL);
if (!aFont) return;
CTFontRef newFont = CTFontCreateCopyWithSymbolicTraits(aFont, 0.0, NULL, kCTFontItalicTrait, kCTFontBoldTrait); //將默認黑體字設置為其它字體
[self removeAttribute:(NSString*)kCTFontAttributeName range:textRange];
[self addAttribute:(NSString*)kCTFontAttributeName value:(id)newFont range:textRange];
CFRelease(aFont);
CFRelease(newFont);
//設置字體顏色
[self removeAttribute:(NSString*)kCTForegroundColorAttributeName range:textRange];
[self addAttribute:(NSString*)kCTForegroundColorAttributeName value:(id)textColor.CGColor range:textRange];
//設置對齊 換行
CTTextAlignment coreTextAlign = kCTLeftTextAlignment;
CTLineBreakMode coreTextLBMode = kCTLineBreakByCharWrapping;
CTParagraphStyleSetting paraStyles[2] =
{
{.spec = kCTParagraphStyleSpecifierAlignment, .valueSize = sizeof(CTTextAlignment), .value = (const void*)&coreTextAlign},
{.spec = kCTParagraphStyleSpecifierLineBreakMode, .valueSize = sizeof(CTLineBreakMode), .value = (const void*)&coreTextLBMode},
};
CTParagraphStyleRef aStyle = CTParagraphStyleCreate(paraStyles, 2);
[self removeAttribute:(NSString*)kCTParagraphStyleAttributeName range:textRange];
[self addAttribute:(NSString*)kCTParagraphStyleAttributeName value:(id)aStyle range:textRange];
CFRelease(aStyle);
(2)Draw NSAttributedString
CGContextRef cgc = UIGraphicsGetCurrentContext();
CGContextSaveGState(cgc);
//圖像方向轉換
CGContextConcatCTM(cgc, CGAffineTransformScale(CGAffineTransformMakeTranslation(0, self.bounds.size.height), 1.f, -1.f));
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)weiBoText);
drawingRect = self.bounds;
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, drawingRect);
textFrame = CTFramesetterCreateFrame(framesetter,CFRangeMake(0,0), path, NULL);
CGPathRelease(path);
CFRelease(framesetter);
CTFrameDraw(textFrame, cgc);
CGContextRestoreGState(cgc);
(3)圖文混排
CTFrameRef textFrame // coreText 的 frame
CTLineRef line // coreText 的 line
CTRunRef run // line 中的部分文字
相關方法:
CFArrayRef CTFrameGetLines (CTFrameRef frame ) //獲取包含CTLineRef的數組
void CTFrameGetLineOrigins(
CTFrameRef frame,
CFRange range,
CGPoint origins[] ) //獲取所有CTLineRef的原點
CFRange CTLineGetStringRange (CTLineRef line ) //獲取line中文字在整段文字中的Range
CFArrayRef CTLineGetGlyphRuns (CTLineRef line ) //獲取line中包含所有run的數組
CFRange CTRunGetStringRange (CTRunRef run ) //獲取run在整段文字中的Range
CFIndex CTLineGetStringIndexForPosition(
CTLineRef line,
CGPoint position ) //獲取點擊處position文字在整段文字中的index
CGFloat CTLineGetOffsetForStringIndex(
CTLineRef line,
CFIndex charIndex,
CGFloat* secondaryOffset ) //獲取整段文字中charIndex位置的字符相對line的原點的x值
主要步驟:
1)計算并存儲文字中保含的所有表情文字及其Range
2)替換表情文字為指定寬度的NSAttributedString
CTRunDelegateCallbacks callbacks;
callbacks.version = kCTRunDelegateVersion1;
callbacks.getAscent = ascentCallback;
callbacks.getDescent = descentCallback;
callbacks.getWidth = widthCallback;
callbacks.dealloc = deallocCallback;
CTRunDelegateRef runDelegate = CTRunDelegateCreate(&callbacks, NULL);
NSDictionary *attrDictionaryDelegate = [NSDictionary dictionaryWithObjectsAndKeys:
(id)runDelegate, (NSString*)kCTRunDelegateAttributeName,
[UIColor clearColor].CGColor,(NSString*)kCTForegroundColorAttributeName,
nil];
NSAttributedString *faceAttributedString = [[NSAttributedString alloc] initWithString:@"*" attributes:attrDictionaryDelegate];
[weiBoText replaceCharactersInRange:faceRange withAttributedString:faceAttributedString];
[faceAttributedString release];
3) 根據保存的表情文字的Range計算表情圖片的Frame
textFrame 通過CTFrameGetLines 獲取所有line的數組 lineArray
遍歷lineArray中的line通過CTLineGetGlyphRuns獲取line中包含run的數組 runArray
遍歷runArray中的run 通過CTRunGetStringRange獲取run的Range
判斷表情文字的location是否在run的Range
如果在 通過CTLineGetOffsetForStringIndex獲取x的值 y的值為line原點的值
4)Draw表情圖片到計算獲取到的Frame
(3)點擊文字觸發事件
主要步驟:
1) 根據touch事件獲取點point
2) textFrame 通過CTFrameGetLineOrigins獲取所有line的原點
3) 比較point和line原點的y值獲取點擊處于哪個line
4) line、point 通過CTLineGetStringIndexForPosition獲取到點擊字符在整段文字中的 index
5) NSAttributedString 通過index 用方法-(NSDictionary *)attributesAtIndex:(NSUInteger)location effectiveRange:(NSRangePointer)range 可以獲取到點擊到的NSAttributedString中存儲的NSDictionary
6) 通過NSDictionary中存儲的信息判斷點擊的哪種文字類型分別處理
感謝各位的閱讀!關于“IOS開發有用的小知識點有哪些”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。