• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • iOS開發筆記(IOS7回歸)



    <---點擊左上角目錄,可以快速查找這里是否有你遇到的問題條目<---


    1,iOS中如何設置項目/文件是否支持ARC

    舊工程配置arc方案:

    1,直接在targets->build phases中修改compiler Flags,是否支持arc。添加:-fobjc-arc,就可以讓舊項目支持arc。如果想讓原來支持arc的不使用arc則添加-fno-objc-arc


    因為在build phases中可以改變是否支持arc,所以應該在代碼中添加判斷是否支持arc,這樣不管以后.m的arc是否改變,都不用再次調整代碼。

    下面是一個.h文件(附件中也上傳了.h),整合了arc的各種屬性、release判斷,直接#import在你想使用arc的類中即可。

    #ifndef paixiu_PXISARC_h
    #define paixiu_PXISARC_h

    #ifndef PX_STRONG
    #if __has_feature(objc_arc)
    #define PX_STRONG strong
    #else
    #define PX_STRONG retain
    #endif
    #endif

    #ifndef PX_WEAK
    #if __has_feature(objc_arc_weak)
    #define PX_WEAK weak
    #elif __has_feature(objc_arc)
    #define PX_WEAK unsafe_unretained
    #else
    #define PX_WEAK assign
    #endif
    #endif

    #if __has_feature(objc_arc)
    #define PX_AUTORELEASE(expression)expression
    #define PX_RELEASE(expression)expression
    #define PX_RETAIN(expression)expression
    #else
    #define PX_AUTORELEASE(expression) [expressionautorelease]
    #define PX_RELEASE(expression) [expressionrelease]
    #define PX_RETAIN(expression) [expressionretain]
    #endif

    #endif

    說明:在arc中,strong對應原來的retain與copy,weak對應原來的assign。

    EX:舉例使用autorelease:

    NSArray*testArray =PX_AUTORELEASE([[NSArrayalloc]init]);
    //如果支持arctestArray就只是alloc init,release的事情由系統來做。

    //如果不支持arc,那這條語句相當于:
    NSArray*testArray = [[[NSArray alloc] init] autorelease];



    這樣不管以后改不改arc,都不會內存泄漏了 .

    所以,arc的使用有兩點:

    A:在build phases中修改compiler Flags值。
    B:在代碼中判斷是否支持arc,包括對屬性(property)、釋放(release)的判斷。

    3,在dealloc中需要這樣做:

    類如果注冊了通知(觀察者模式),需要remove掉。這個不管是否支持arc,都必須要做的。

    - (void)dealloc {

    [[NSNotificationCenterdefaultCenter]removeObserver:self];//如果注冊了通知的話。

    [selfremoveObserver:selfforKeyPath:keyPath];//如果注冊了kvo的話。

    #if !__has_feature(objc_arc) //在這里也需要判斷是否支持arc,支持的話就執行舊工程中該release的語句.
    [array release]; //array代表alloc但沒有autorelease的變量
    [superdealloc];
    #endif
    }

    4,另外加點block的判斷,這個是在4.0以后有的,當然也可以不進行判斷,因為現在大多數都4.0以后了。

    #if NS_BLOCKS_AVAILABLE

    #endif

    總結:
    1,arc的設置是在build phases中修改compiler Flags的值。
    2,如果使用了arc,在你的代碼中不可以使用retain, release, autorelease,如果使用的話會報錯。
    3,如果使用了arc,在@property聲明中,用strong代替retain。在支持__unsafe_unretained的情況下,__unsafe_unretained相當于assign。
    4,如果使用了arc,NSAutoReleasePool也不能使用,測試發現,用@autoreleasepool代替,不會編譯報錯。
    總之,一切你之前“背過”的那幾條內存管理規則,你都不用去管了。而且,個人感覺,用arc代碼清晰很多,而且效率也提高了些。

    ——————————————————————————————————

    對于arc屬性可能寫的不太清楚,這里附加點:

    1,不管在不在arc下,object對象都有強引用、弱引用之分,當需要保持(擁有)其他對象的時候,需要retain。
    2,在arc中,使用strong、weak修飾的變量,當對象不再存在的時候會被置為nil。而[align=-webkit-left]__unsafe_unretained不會被置為nil,會成為野指針,是不安全的,再次訪問可能造成錯誤。
    [align=-webkit-left]
    3,引用關鍵字:arc中,變量聲明默認為_strong.
    出自:http://www.cocoachina.com/bbs/read.php?tid=122591


    2,iOS設備的硬件適配 (關于armv6, armv7, armv7s )

    armv6、armv7、armv7s是arm CPU的指令集,原則上是向下兼容的

    armv6:iPhone 2G/3G,iPod 1G/2G

    armv7:iPhone 3GS/4/4s,iPod 3G/4G,iPad 1G/2G/3G

    armv7s:iPhone5

    如果引用到第三方的庫,以前在iphone4s下編譯沒有問題,但是換成iphone5之后,提示:


    Undefined symbols for architecture armv7s:
    "_OBJC_CLASS_$_AMapView", referenced from:
    objc-class-ref in libMAMapKit.a(MAMapView.o)
    ld: symbol(s) not found for architecture armv7s

    也就是說,引用自XX.a靜態庫的XX類不支持armv7s指令。你引用的靜態庫不支持armv7s,要想順利編譯通過,要么通知開發修改,等待支持了之后再測;要么在target的build settings中的valid Architectures 將armv7s先暫時去掉,編譯就可以成功。(暫時的辦法)


    3,關于Build Active Architecture Only屬性

    這個屬性設置為yes,是為了debug的時候編譯速度更快,它只編譯當前的architecture版本。
    而設置為no時,會編譯所有的版本。
    這個是設備對應的architecture:
    armv6:iPhone 2G/3G,iPod 1G/2G
    armv7:iPhone 3GS/4/4s,iPod 3G/4G,iPad 1G/2G/3G
    armv7s:iPhone5, iPod5

    編譯出的版本是向下兼容的,比如你設置此值為yes,用iphone4編譯出來的是armv7版本的,iphone5也可以運行,但是armv6的設備就不能運行。

    所以,一般debug的時候可以選擇設置為yes,release的時候要改為no,以適應不同設備。

    Build Phases中的Architectures和Valid Architectures的區別

    Architectures 這代表,在這個項目里你想要Xcode編譯的目標設備列表。

    Valid Architectures 一般來說是不需要更改的,和Architectures一樣就可以。

    在Xcode5.0里的Valid Architectures設置里,有2個選項:

    1. 默認為standard architectures (including 64-bit)(armv7,armv7s,arm64),這樣設置,你的Deployment target最低只能設置為 6.0,(在Xcode5.0.1 之后,最低能夠兼容IOS 5.1.1);
    2. standard architectures (armv7,armv7s),這樣設置,你的Deployment target最低能設置為 4.3;

    使用standard architectures (including 64-bit)(armv7,armv7s,arm64)參數,
    則打的包里面有32位、64位兩份代碼,
    在iPhone5s(iPhone5s的cpu是64位的)下,會首選運行64位代碼包,
    其余的iPhone(其余iPhone都是32位的,iPhone5c也是32位),
    只能運行32位包,
    但是包含兩種架構的代碼包,只有運行在ios6,ios7系統上。
    這也就是說,這種打包方式,對手機幾乎沒啥要求,但是對系統有要求,即ios6以上。

    而使用standard architectures (armv7,armv7s)參數,
    則打的包里只有32位代碼,
    iPhone5s的cpu是64位,但是可以兼容32位代碼,即可以運行32位代碼。但是這會降低iPhone5s的性能,原因下面的參考有解釋。
    其余的iPhone對32位代碼包更沒問題,
    而32位代碼包,對系統也幾乎也沒什么限制。

    所以總結如下:
    要發揮iPhone5s的64位性能,就要包含64位包,那么系統最低要求為ios6。
    如果要兼容ios5以及更低的系統,只能打32位的包,系統都能通用,但是會喪失iPhone5s的性能。

    所有IOS設備詳情列表 List of iOS devices - Wikipedia, the free encyclopedia

    armv6:iPhone 2G/3G,iPod 1G/2G
    armv7:iPhone 3GS/4/4s,iPod 3G/4G,iPad 1G/2G/3G ,iPad Mini 1
    armv7s:iPhone5 ,iPhone5C ,iPad4
    armv8:iPhone5S ,iPad5(iPad Air), iPad Mini 2(iPad Mini Retina)

    iOS 7: 如何為iPhone 5S編譯64位應用。

    Xcode 5編譯的iOS 7程序包含了32位和64位兩套二進制代碼,在32位的iOS系統上會調用32位的二進制代碼,在64位系統上會調用64位的二進制代碼,以此來解決向后兼容的問題。

    同時,考慮到很多32位的程序可能在沒有重新編譯的情況下部署到64位系統上,64位的iOS系統中帶有兩套FrameWork,一套是32位的,一套是64位的。
    當64位的iOS系統運行原來的32位程序時,系統會調用32位的FrameWork作為底層支撐,當系統運行64位程序時,系統會調用64位的FrameWork作為底層支撐。

    也就是說,當一個iPhone 5S上同時運行32位程序和64位程序時,系統同時將32位和64位兩套FrameWork載入了內存中,所以消耗的內存也比較多。

    如果一臺64位的iOS設備上運行的所有程序都是為64位系統編譯過的,iOS系統將只載入64位的FrameWork,這將節省好多內存。所以,如果大家都可以快速將程序傳換成64位的,iOS將跑得更快。真的是“大家好才是真的好”。


    出處:http://my.oschina.net/shede333/blog/172785#OSC_h3_10


    Xcode 6更新默認不支持armv7s架構http://www.cocoachina.com/ios/20141013/9897.html


    4,在ARC下保留dealloc的原因

    dealloc 方法中 我們不再被允許調用 [release] 了, 也不允許調用 [super dealloc]。
    唯一一個留著 dealloc 方法的原因就是, 你需要釋放一些不在 ARC 控制下的資源。 例如 Core Foundation 對象中調用 CFRelease(), 對那些通過 malloc() 分配的內存調用 free(), 注銷通知,停止 Tiner, 等等。
    如果你是一個對象的代理的話,有時必須顯式的斷開和它的連接,但通常這都是自動的。 大部分情況下,代理都是弱引用, 當一個即將被釋放的對象是其他對象的代理的話, 當這個對象被銷毀時,代理指針將會被自動設置為 nil。 弱指針在這之后會被自動清楚。
    另外, 在你的 dealloc 方法中, 你仍然可以使用實例變量, 因為他們在這時候還沒被釋放掉。 在 dealloc 返回之前,都不會被釋放。

    http://www.2cto.com/kf/201405/299286.html


    5,iOS中,在類的源文件(.m)中,@interface部分的作用?

    此@interface部分為類擴展(extension)。
    其被設計出來就是為了解決兩個問題的,其一,定義類私有方法的地方。其二,實現public readonly,private readwrite的property(意思是在h頭文件中定義一個屬性對外是readonly的,但在類的內部希望是可讀寫的,所以可以在m源文件中的@interface部分重新定義此屬性為readwrite,此時此屬性對外是只讀的,對內是讀寫的)。
    此外,也可在此部分申明變量和屬性,但申明的變量,屬性和方法均為私有的,只能夠被當前類訪問,相當于private。


    所以在類中看到類似如下的描述:


    只是類別(category)的名字叫:prairie,并非跟@private私有 有任何關系。,

    6,Objective-C中public、protected、private的使用

    @public,@protected,@private
    @public 是共有成員,在類本身極其外部都可以訪問到,@protected 只有子類和本身可以訪問該對象,默認就是這個;@private,這里聲明的就是私有成員,只有本類可以訪問。

    static方法

    當方法前是使用"+"來修飾并且聲明在頭文件中,則說明該方法相當于c++中的static方法,通過類直接調用。但是需要注意的是,雖然這樣的方法可以通過類直接調用,但是不可以通過對象調用。
    public方法
    當方法前是使用"-"來修飾并且聲明在頭文件中,則該方法可以通過類的對象進行調用。
    private方法
    Objective-C中的private方法是通過category實現的,在實現文件中我們聲明一個類的category,在這里面的方法就是private方法。類的對象是不可以進行調用的,同樣由于該方法的聲名是在類的實現文件中,所以子類也是不能重寫該方法的。

    .h文件

    #import <Foundation/Foundation.h>
    
    @interface Grammar : NSObject {
     
    
       @public
            NSString* publicString;
       
        @protected
            NSString* protectedString;
       
        @private
            NSString* privateString;
    }
    
    NSString* staticString;
    
    @property (nonatomic, retain) NSString* publicString;
    
    + (void)staticMethod;
    - (void)publicMethod;
    
    @end

    .m文件

    #import "Grammar.h"
    
    //私有方法以category方式實現
    #pragma mark -
    #pragma mark Grammar(private)
    
    @interface Grammar(private)
    
    - (void)privateMethod;
    
    @end
    
    
    
    #pragma mark -
    #pragma mark Grammar
    
    @implementation Grammar
    
    @synthesize publicString;
    
    
    #pragma mark -
    #pragma mark Public Method
    
    + (void)staticMethod
    {
    }
    
    - (void)publicMethod
    {
    }
    
    #pragma mark -
    #pragma mark Private Method
    
    - (void)privateMethod
    {
    }
    
    @end

    7,Prefix.pch的作用和用法

    TestDemo_Prefix.pch:擴展名.pch表示"precompiled header",這是一個你工程要用到的來自于外部框架的頭文件列表。xcode將編譯這些頭到文件,這將減少在選擇BuildBuild and Go時編譯項目的時間。通常用到的頭文件已經自動包含到了pch(比如:UIKit、Foundation),系統編譯每個cpp文件前,都會先include這個文件。這樣就節省了添加include的時間。還有就是可以再這里面放入宏,在整個工程中都可以用。

    在XCode6中, 默認是沒有pch文件的,如果我們想使用pch文件,需要手動添加,添加步驟如下:


    newFile-Other-empty


    (1)、找工程的Targets->Build Settings->Apple LLVM 6.0 - Language


    (2)在Prefix Header下面的Debug和Release下添加$(SRCROOT)/工程名/pch文件


    8,initWithNibName和initWithCoder

    創建了一個nib文件,沒有和其他可被實例化的類有直接或間接關系的時候,這個類或這些類(一個nib文件俺也可能包含多個類)是沒有機會被實例化的,所以這種情況只是通過ib創建了一個類,而沒有實例化.真正的實例化還需要通過在Xcode用代碼來讀取這個nib文件。所以initWithNibName這個方法是某一個和IB關聯的Controller的類,通過Xcode實例化controller的時候會調用的。

    initWithCoder是一個類在IB中創建但在xocdde中被實例化時被調用的.比如,通過IB創建一個controller的nib文件,然后在xocde中通過initWithNibName來實例化這個controller,那么這個controller的initWithCoder會被調用.

    9,dealloc函數中 super dealloc 的使用時機

    我們定義的全局變量都是在 - (void)dealloc 函數中釋放的,里面繼承了一個[super dealloc]方法,
    有些同學平時自己釋放內存都是寫在 [super dealloc]的后面,但是在Objective-c 中不能這樣寫,所有的釋放都必須寫在 [super dealloc]的前面。

    -------錯誤的寫法--------
    - (void)dealloc
    {
    [super dealloc];
    [XXX release];
    ......
    }
    -------正確的寫法--------
    - (void)dealloc
    {
    [XXX release];
    [super dealloc];
    ......
    }
    原因是:“你所創建的每個類都是從父類,根類繼承來的,有很多實例變量也會繼承過來,這部分變量有時候會在你的程序內使用,它們不會自動釋放內存,你需要調用父類的 dealloc方法來釋放,然而在此之前你需要先把自己所寫類中的變量內存先釋放掉,否則就會造成你本類中的內存積壓,造成泄漏”。


    10,通過GestureRecognizer實現點擊任意區域隱藏鍵盤

    基本思想如下:
    1. 在ViewController載入的時候,將鍵盤顯示和消失的Notification添加到self.view里。
    2. 分別在鍵盤顯示和消失時添加和刪除TapGestureRecognizer

    - (void)viewDidLoad {
        [super viewDidLoad];
        [self setKeyBoardAutoHidden];
    }
    - (void)setKeyBoardAutoHidden{
        NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
        //SingleTap Gesture
        UITapGestureRecognizer *singleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(backgroundTapDismissKeyboard:)];
        
        NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
        
        //UIKeyboardWillShowNotification
        [notificationCenter addObserverForName:UIKeyboardWillShowNotification object:nil queue:mainQueue usingBlock:^(NSNotification *note) {
            [self.view addGestureRecognizer:singleTapGesture];
        }];
        
        //UIKeyboardWillHideNotification
        [notificationCenter addObserverForName:UIKeyboardWillHideNotification object:nil queue:mainQueue usingBlock:^(NSNotification *note) {
            [self.view addGestureRecognizer:singleTapGesture];
        }];
    
    }
    - (void) backgroundTapDismissKeyboard:(UIGestureRecognizer *) gestureRecognizer{
        //將self.view里所有的subview的first responder 都resign掉
        [self.view endEditing:YES];
    }


    11,NavigationBar中通過code方式對背景顏色和title字體顏色更改

    背景顏色:

    [self.navigationController.navigationBar setBarTintColor:[UIColor colorWithRed:20/255.0 green:155/255.0 blue:213/255.0 alpha:1.0]];
    字體屬性修改:

        [self.navigationController.navigationBar setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
                                                                         [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0],
                                                                         UITextAttributeTextColor,
                                                                         [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8],
                                                                         UITextAttributeTextShadowColor,
                                                                         [NSValue valueWithUIOffset:UIOffsetMake(0, -1)],
                                                                         UITextAttributeTextShadowOffset,
                                                                         [UIFont fontWithName:@"Arial-Bold" size:0.0],
                                                                         UITextAttributeFont,nil]]; 
    有關此屬性的官方鏈接:https://developer.apple.com/library/ios/documentation/UIKit/Reference/UINavigationBar_Class/index.html#//apple_ref/doc/uid/TP40006887

    12,如何理解 File's Owner 與 First Responder

    xib和nib

    簡單地說,就是xib和nib都是一些對象的描述,而前者是xml格式,后者是一種二進制格式。二者的使用上沒有什么區別,xcode/IB是兩種格式都支持的。xib比nib有個很明顯的好處,就是xib可以很方便地進行diff操作。xib是文本文件,所以在版本控制方面比nib有優勢。可能有人會說,反序列化的時候,xib肯定比nib慢很多吧。這個不需要擔心的,因為在build的時候,xcode會把xib都轉換為nib。最終用戶使用的將會是nib內容,而不是xib。

    File's Owner

    File's Owner 表示視圖控制器。UIViewController(或其子類)在生成的時候,首先會尋找相應的.xib去生成,于是controller的實例(instance)就把.xib載入內存,并成為FIle's Owner。所以我們定義的controller是這個.xib的custom class。并且需要把這個FIle Owner上的outlet連到某個控件上去。(Action也同樣道理)

    它不一定就是某個viewcontroller,換個角度,如果我們看.xib文件,發現它有個File Owner。其實就是我們用來設定,究竟是那個Object來讀取并載入這個.xib文件,也就是說,誰own這個文件。

    [[NSBundle mainBundle] loadNibNamed:@"UnitTableCell" owner:self options:nil] IB里面創造都是一些對象 filer'owner意思是這些對象創建出來后要掛載到那個對象里面 (owner:self)

    First Responder

    First Responder 在用戶與屏幕交互時變化。例如,假設有一個表單。當用戶觸摸表單中的某個文本域時,那個文本域將成為活動文本域,并擔當 First Responder 的角色。如實現觸摸某個位置關閉當前鍵盤的事件中:[currentTextField resignFirstResponder];就是告訴receiver,“currentTextField以完成任務,請求辭去 First Responder 的職務。

    13,ScrollView怎樣才能上下或左右滑動?

    scrollerView能否劃動是由它的contentSize 和frame.size來決定的, 只有內容比實際的顯示尺寸大scroll才可以劃動。

    contentSize

       [self.mScrollView setContentSize:CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height)];<span style="font-size: 14px;">//設置scrollView的滾動范圍</span>
    <pre name="code" class="objc" style="color: rgb(51, 51, 51); font-size: 14px; line-height: 26px;">contentOffset 

    
    
       scrollView.contentOffset = CGPointMake(0, 200);<span style="font-family: Arial;">// 設置scrollView的滾動偏移量</span>

    contentInset默認 UIEdgeInsetsZero,用來設置scrollView的額外滾動區域。
       scrollView.contentInset = UIEdgeInsetsMake(100, 0, 0, 0);<span style="color: rgb(51, 51, 51); font-family: Arial; font-size: 14px; line-height: 26px;">// 設置scrollView額外頂部滾動區域:(UIEdgeInsetsMake是逆時針設置,上左下右)</span>
    bounces
       scrollView.bounces = NO;//<span style="color: rgb(51, 51, 51); font-family: Arial; font-size: 14px; line-height: 26px;">默認為YES,用來設置scrollView的彈簧效果</span>



    14,如何創建CGColorRef在view.layer.borderColor上使用?

    方法一:寫RGB轉換方法

    +(CGColorRef) getColorFromRed:(int)red Green:(int)green Blue:(int)blue Alpha:(int)alpha  
    {  
        CGFloat r = (CGFloat) red/255.0;  
        CGFloat g = (CGFloat) green/255.0;  
        CGFloat b = (CGFloat) blue/255.0;  
        CGFloat a = (CGFloat) alpha/255.0;    
        CGFloat components[4] = {r,g,b,a};  
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();  
      
        CGColorRef color = (CGColorRef)[(id)CGColorCreate(colorSpace, components) autorelease];  
        CGColorSpaceRelease(colorSpace);  
          
        return color;  
    }

    方法二:直接利用UIColor的CGColor屬性

        textview.layer.borderColor = [UIColor darkGrayColor].CGColor;
        
        UIColor *customColor  = [UIColor colorWithRed:123/255.0 green:123/255.0 blue:123/255.0 alpha:1.0];
        textview.layer.borderColor = customColor.CGColor;


    15,ios中實現多行輸入的UITextField

    UITextField本身不支持多行輸入,我們也沒必要去重寫重繪,簡單點來說用UITextView便可實現:

        UITextView *textview = [[UITextView alloc] initWithFrame:CGRectMake(50, 120, 300, 200)];
        textview.layer.cornerRadius = 6;
        textview.layer.masksToBounds = YES;
        //textview.layer.borderColor = [UIColor darkGrayColor].CGColor;
        UIColor *customColor  = [UIColor colorWithRed:123/255.0 green:123/255.0 blue:123/255.0 alpha:1.0];
        textview.layer.borderColor = customColor.CGColor;
        textview.layer.borderWidth = 2.0;
        [self.view addSubview:textview];
    效果圖如下:


    16,UITextField、UITextView 鍵盤遮擋住輸入框,如何上移View使之顯示

    將輸入框所對應的ViewController.h設置實現了UITextFieldDelegate或UITextViewDelegate協議

    在ViewController.m文件中實現UITextFieldDelegate的三個方法:

    #pragma -mark UITextField Delegate
    -(void)textFieldDidBeginEditing:(UITextField *)textField{
        
        CGRect frame = textField.frame;
        
    	//在這里我多加了62,(加上了輸入中文選擇文字的view高度)這個依據自己需求而定
        int offset = (frame.origin.y+62)-(self.view.frame.size.height-216.0);//鍵盤高度216
    
        [UIView beginAnimations:@"ResizeForKeyboard" context:nil];
        
        [UIView setAnimationDuration:0.30f];//動畫持續時間
        
        if (offset>0) {
    	//將視圖的Y坐標向上移動offset個單位,以使下面騰出地方用于軟鍵盤的顯示
            self.view.frame = CGRectMake(0.0f, -offset, self.view.frame.size.width, self.view.frame.size.height);
            [UIView commitAnimations];
        }
        
    }
    
    /**
     *當用戶按下return鍵或者按回車鍵,我們注銷KeyBoard響應,它會自動調用textFieldDidEndEditing函數
     */
    -(BOOL)textFieldShouldReturn:(UITextField *)textField{
    
        [textField resignFirstResponder];
        
        return YES;
    }
    
    
    -(void)textFieldDidEndEditing:(UITextField *)textField{
    	//輸入框編輯完成以后,當鍵盤即將消失時,將視圖恢復到原始狀態
        self.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
        
    }


    17,終端中執行purge命令:Unable to purge disk buffers: Operation not permitted

    OSX 10.9 Mavericks系統下的內存清理命令改了,執行:sudo purge 即可 執行時會提示要求輸入管理員密碼。



    18,設置RGB顏色一個非常有用的宏

    #define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
    使用方式:

    [[UINavigationBar appearance] setBarTintColor:UIColorFromRGB(0x067AB5)];

    19,Interface Builder could not open the document "xxx.xib" because it does not exist.


    解決辦法:選中項目-Target-Build Phases-Compile Sources,刪除相應不存在的的文件



    20,UITextField、UITextView 響應 鍵盤的return(完成鍵)

    實現UITextFieldDelegate:

    #pragma -mark UITextFieldDelegate
    -(BOOL)textFieldShouldReturn:(UITextField *)textField{
        
        NSString *userIdStr = [userIdField text];
        [self doLogin:userIdStr];
        
        return YES;
    }
    
    但是 UITextView的代理UITextViewDelegate 里面并沒有這樣的回調。
    但是有別的方法可以實現,UITextViewDelegate里面有這樣一個代理函數:

    - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
    
    這個函數的最后一個參數text代表你每次輸入的的那個字,所以:
    - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
        if ([text isEqualToString:@"\n"]){ //判斷輸入的字是否是回車,即按下return
            //在這里做你響應return鍵的代碼
            return NO; //這里返回NO,就代表return鍵值失效,即頁面上按下return,不會出現換行,如果為yes,則輸入頁面會換行
        }
    
        return YES;
    }

    21,iOS7實現帶文本輸入框的UIAlertView及獲取TextField文本內容

    實現:

        if (customAlertView==nil) {
            customAlertView = [[UIAlertView alloc] initWithTitle:@"自定義服務器地址" message:nil delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"確定", nil];
        }
        [customAlertView setAlertViewStyle:UIAlertViewStyleLoginAndPasswordInput];
        
        UITextField *nameField = [customAlertView textFieldAtIndex:0];
        nameField.placeholder = @"請輸入一個名稱";
        
        UITextField *urlField = [customAlertView textFieldAtIndex:1];
        [urlField setSecureTextEntry:NO];
        urlField.placeholder = @"請輸入一個URL";
        urlField.text = @"http://";
        
        [customAlertView show];

    實現UIAlertViewDelegate

    -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    
        if (buttonIndex == alertView.firstOtherButtonIndex) {
            UITextField *nameField = [alertView textFieldAtIndex:0];
            UITextField *urlField = [alertView textFieldAtIndex:1];
            //TODO
        }
        
        
        
    }
    

    效果:



    22,viewDidLoad, viewWillDisappear, viewWillAppear等區別及各自的加載順序

    當一個視圖控制器被創建,并在屏幕上顯示的時候。 代碼的執行順序


    1、 alloc 創建對象,分配空間


    2、init (initWithNibName) 初始化對象,初始化數據


    3、loadView 從nib載入視圖 ,通常這一步不需要去干涉。除非你沒有使用xib文件創建視圖


    4、viewDidLoad 載入完成,可以進行自定義數據以及動態創建其他控件


    5、viewWillAppear 視圖將出現在屏幕之前,馬上這個視圖就會被展現在屏幕上了


    6、viewDidAppear 視圖已在屏幕上渲染完成


    當一個視圖被移除屏幕并且銷毀的時候的執行順序,這個順序差不多和上面的相反


    1、viewWillDisappear 視圖將被從屏幕上移除之前執行


    2、viewDidDisappear 視圖已經被從屏幕上移除,用戶看不到這個視圖了


    3、dealloc 視圖被銷毀,此處需要對你在init和viewDidLoad中創建的對象進行釋放


    23,ios7中viewDidLoad和viewWillAppear中self.view.frame的size不一致

    在viewDidLoad里打印self.view.frame.size.height是568,在viewWillAppear方法打印self.view.frame.size.height都是480,很奇怪,原來是因為我用xib創建了view,xib那里size設置的是retina4,但是模擬器(真機)是retina3.5;


    viewdidload里面初始化的是4寸的view 568高度 但是在顯示之前 就是viewwillappear這個函數里面發現是3.5的手機 然后他就自適應成了3.5的尺寸 也就是480的高度了之后所有的地方都是480了 。


    24,UIAlertView和UIAlertController通過文本框內容判斷讓按鈕動態可用或不可用

    先說UIAlertView中如何實現

        customAlertView = [[UIAlertView alloc] initWithTitle:@“title” message:nil delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];
        [customAlertView setAlertViewStyle:UIAlertViewStyleLoginAndPasswordInput];
        
        UITextField *nameField = [customAlertView textFieldAtIndex:0];
        nameField.placeholder = getString(@"inputalias");
        
        UITextField *urlField = [customAlertView textFieldAtIndex:1];
        [urlField setSecureTextEntry:NO];
        urlField.text = @"http://";
        
        [customAlertView show];

    需要實現UIAlertViewDelegate

    #pragma -mark UIAlertViewDelegate
    -(BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView{
    
        UITextField *aliasfield = [alertView textFieldAtIndex:0];
        UITextField *urlfield =  [alertView textFieldAtIndex:1];
        
        //alias和url都有值才可以保存
        if (aliasfield.text.length>0 && urlfield.text.length>7) {
            return YES;
        }
        
        return NO;
    }

    看一下效果:


    當我們輸入符合規定的字符后,alertViewShouldEnableFirstOtherButton(每當有事件發生,會不斷回調此函數)中做判斷,返回YES的話,右側OK的按鈕就可用了。

    UIAlertController

    如果我們想要實現UIAlertView中的委托方法alertViewShouldEnableOtherButton:方法的話可能會有一些復雜。假定我們要讓“登錄”文本框中至少有3個字符才能**“好的”按鈕。很遺憾的是,在UIAlertController中并沒有相應的委托方法,因此我們需要向“登錄”文本框中添加一個Observer。Observer模式定義對象間的一對多的依賴關系,當一個對象的狀態發生改變時, 所有依賴于它的對象都得到通知并被自動更新。我們可以在構造代碼塊中添加如下的代碼片段來實現。

    [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField){
        ...
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(alertTextFieldDidChange:) name:UITextFieldTextDidChangeNotification object:textField];
    }];

    當視圖控制器釋放的時候我們需要移除這個Observer,我們通過在每個按鈕動作的handler代碼塊(還有其他任何可能釋放視圖控制器的地方)中添加合適的代碼來實現它。比如說在okAction這個按鈕動作中:

    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        ...
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
    }];

    在顯示對話框之前,我們要凍結“好的”按鈕

    okAction.enabled = NO;

    接下來,在通知觀察者(notification observer)中,我們需要在**按鈕狀態前檢查“登錄”文本框的內容。

    - (void)alertTextFieldDidChange:(NSNotification *)notification{
        UIAlertController *alertController = (UIAlertController *)self.presentedViewController;
        if (alertController) {
            UITextField *login = alertController.textFields.firstObject;
            UIAlertAction *okAction = alertController.actions.lastObject;
            okAction.enabled = login.text.length > 2;
        }
    }


    25,iOS:關于獲取網絡類型和運營商信息

    Apple的Reachability Sample看起來不錯,但是只可以判斷是否連接到互聯網和是否連接Wifi,但是無法判斷運營商網絡類型(2G/3G等)。

    第一種方法就是嘗試從狀態欄中獲取網絡類型,代碼如下:【私有API】

    +(NSString *)getNetWorkStates{
    UIApplication *app = [UIApplication sharedApplication];
    NSArray *children = [[[app valueForKeyPath:@"statusBar"]valueForKeyPath:@"foregroundView"]subviews];
        NSString *state = [[NSString alloc]init];
        int netType = 0;
    //獲取到網絡返回碼
        for (id child in children) {
    if ([child isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {
                //獲取到狀態欄
                netType = [[child valueForKeyPath:@"dataNetworkType"]intValue];
    
                switch (netType) {
                    case 0:
                        state = @"無網絡";
                        //無網模式
                        break;
                    case 1:
                        state = @"2G";
                        break;
                    case 2:
                        state = @"3G";
                        break;
                    case 3:
                        state = @"4G";
                        break;
                    case 5:
                    {
                        state = @"WIFI";
                    }
                        break;
                    default:
                        break;
                }
            }
        }
    //根據狀態選擇
        return state;
    }
    基本原理是從UIApplication類型中通過valueForKey獲取內部屬性statusBar。然后篩選一個內部類型(UIStatusBarDataNetworkItemView),最后返回他的dataNetworkType屬性,根據狀態欄獲取網絡狀態,可以區分2G、3G、4G、WIFI,系統的方法,比較快捷,不好的是萬一連接的WIFI沒有聯網的話,識別不到。

    第二種方法是通過SoftwareUpdateServices.framework中的SUNetworkMonitor類型來獲取,參考SO鏈接。同樣也是私有API。

    第三種方法是iOS 7中的公有API,在CTTelephonyNetworkInfo類型中,官方文檔相關API的說明https://developer.apple.com/library/ios/documentation/NetworkingInternet/Reference/CTTelephonyNetworkInfo/index.html

    實現起來就是使用CTTelephonyNetworkInfo類型的currentRadioAccessTechnology方法,代碼如下:

    #import <CoreTelephony/CTTelephonyNetworkInfo.h>
    @property (strong, nonatomic)CTTelephonyNetworkInfo *networkInfo;
    self.networkInfo = [[CTTelephonyNetworkInfo alloc] init];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkChanged) name:CTRadioAccessTechnologyDidChangeNotification object:nil];
    - (void)networkChanged{
    
        //網絡改變,做相關的操作,注意非UI線程
        dispatch_async(dispatch_get_main_queue(), ^{
            self.networkLabel.text = state;
        });
    
    }


    26,使用NSMutableURLRequest以form表單方式POST請求

    直接舉例:

        NSURL* nsurl = [NSURL URLWithString:@"http://www.test.com/login"];
        NSMutableURLRequest* request = [[NSMutableURLRequest alloc]init];
        [request setURL:nsurl];
    把下面的代碼,拷貝到您的項目中即可:

    /**
     * 設置POST以Form表單方式請求
     **/
    + (void)setFormDataRequest:(NSMutableURLRequest *)request fromData:(NSDictionary *)formdata{
        
        NSString *boundary = @"12436041281943726692693274280";
        
        //設置請求體中內容
        NSMutableString *bodyString = [[NSMutableString alloc]init];
        int count = (int)([[formdata allKeys] count]-1);
        for (int i=count; i>=0; i--) {
            
            NSString *key = [formdata allKeys][i];
            NSString *value = [formdata allValues][i];
            if ([key isEqualToString:@"accessToken"]) {
                value = [value substringToIndex:32];
            }
            
            [bodyString appendFormat:@"-----------------------------%@\r\nContent-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n",boundary,key,value];
        }
        
        [bodyString appendFormat:@"-----------------------------%@--\r\n", boundary];
        NSMutableData *bodyData = [[NSMutableData alloc]initWithLength:0];
        NSData *bodyStringData = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
        [bodyData appendData:bodyStringData];
        
        NSString *contentLength = [NSString stringWithFormat:@"%ld",(long)[bodyData length]];
        
        NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=---------------------------%@", boundary];
    
        [request setValue:contentType forHTTPHeaderField:@"Content-Type"];
        [request setValue:contentLength forHTTPHeaderField:@"Content-Length"];
        [request setHTTPBody:bodyData];
        [request setHTTPMethod:@"POST"];
        
    }

    請求的時候我們會發現,HTTPBody的內容是這樣:

    -----------------------------12436041281943726692693274280
    Content-Disposition:form-data;name="from"

    0
    -----------------------------12436041281943726692693274280
    Content-Disposition:form-data;name="role"

    0
    -----------------------------12436041281943726692693274280
    Content-Disposition:form-data;name="password"

    000000
    -----------------------------12436041281943726692693274280
    Content-Disposition:form-data;name="username"

    13800001380
    -----------------------------12436041281943726692693274280--


    而Content-Type是這樣:

    multipart/form-data; boundary=---------------------------12436041281943726692693274280,contentLength:525


    27,Xcode6 使用NSUserDefault 的 plist文件存儲位置

    在Xcode5甚者之前,我們知道,如果用模擬器運行APP,想知道NSUserDefault的plist存放路徑是這樣的:/Users/username/Library/Application Support/iPhone Simulator/模擬器版本/Applications/UDID/Library 的Preferences文件夾下,自己程序命名.plist

    在Xcode6中,程序對使用NSUserDefault方式創建的plist文件的位置進行了更換,具體路徑為:/Users/username/Library/Developer/CoreSimulator/Devices/模擬器UDID/data/Library,Preferences文件夾下,如下圖:


    28,使用NSUserDefaults 讀取和寫入自定義對象(Attempt to set a non-property-list object as an NSUserDefaults value for 錯誤)

    眾所周知,NSUserDefaults只能保存諸如NSArray、NSDictionary、NSData、NSNumber等基本數據類型,如果我們強制保存自定義的類,就會出現這個錯誤:Attempt to set a non-property-list object as an NSUserDefaults value for ,解釋起來:【試圖將一個非屬性列表對象設置為 NSUserDefaults】接下來就說說如何吧自定義的對象保存到NSUserDefaults中去。

    自定義的類實現<NSCoding>協議中的- (id) initWithCoder: (NSCoder *)coder方法和- (void) encodeWithCoder: (NSCoder *)coder方法

    #pragma mark NSCoding
    - (id)initWithCoder:(NSCoder *)aDecoder{
    
        if (self == [super init]) {
            alias = [aDecoder decodeObjectForKey:JSON_NAME];
            mobile = [aDecoder decodeObjectForKey:JSON_MOBILE];
            signtime = [[aDecoder decodeObjectForKey:JSON_TIMESTAMP] longValue];
            endtime = [[aDecoder decodeObjectForKey:JSON_END_TIME] longValue];
            cmobile = [aDecoder decodeObjectForKey:JSON_CMOBILE];
        }
        return self;
    }
    
    - (void)encodeWithCoder:(NSCoder *)aCoder{
    
        [aCoder encodeObject:alias forKey:JSON_NAME];
        [aCoder encodeObject:mobile forKey:JSON_MOBILE];
        [aCoder encodeObject:[NSNumber numberWithLong:signtime] forKey:JSON_TIMESTAMP];
        [aCoder encodeObject:[NSNumber numberWithLong:endtime] forKey:JSON_END_TIME];
        [aCoder encodeObject:cmobile forKey:JSON_CMOBILE];
    
    }

    保存到NSUSerDefault:

        Terminal *terminal = [[Terminal alloc] init];
        
        terminal.alias = [dict objectForKey:JSON_NAME];
        terminal.mobile = [dict objectForKey:JSON_MOBILE];
        terminal.signtime = [[dict objectForKey:JSON_TIMESTAMP] longValue];
        terminal.endtime = [[dict objectForKey:JSON_END_TIME] longValue];
        terminal.cmobile = [dict objectForKey:JSON_CMOBILE];
        
        NSData *data = [NSKeyedArchiver archivedDataWithRootObject:terminal];
        
        [userDefaults setObject:data forKey:"test"];
        
        [userDefaults synchronize];

    也就是說,我們保存自定義對象時,是使用NSKeyedArchiver 把數據歸檔為NSData對象,然后把NSData存儲到UserDefault中,NSData相當于Model


    讀取:

        NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults];
        
        NSData *data =  [userDefaults objectForKey:"test"];
        
        return [NSKeyedUnarchiver unarchiveObjectWithData:data];
    讀取自定義對象時,先獲取到NSData,然后使用NSKeyedUnarchiver解檔為自定義的對象

    LOG輸出,查看結果:

    2014-12-1016:31:11.815ESO_Etws[1463:60b]alias:Q611-0334
    2014-12-1016:31:11.815ESO_Etws[1463:60b]mobile:13841040334
    2014-12-1016:31:11.815ESO_Etws[1463:60b]signtime:1394529151000
    2014-12-1016:31:11.816ESO_Etws[1463:60b]endtime:1426065151000
    2014-12-1016:31:11.816ESO_Etws[1463:60b]cmobile:

    PS:
    APP升級后,UserDefaults中原有的plist是不會刪除的,除非用戶卸載APP
    清除整個UserDefaults數據的方法:
    NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
    [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];

    29,ios APP初次安裝以及版本更新后,判斷是否需要顯示引導頁的實現方法

    獲取APP版本號,將版本號作為Key(比如Bool類型),存儲在NSuserDefault中,初此安裝打開時,key是不存在的,即進入引導頁面,之后將此key保存起來(保證前面的判斷不會再進入)

    app升級后,判斷新版本號的key,發現沒有,即顯示新版本的引導頁面,然后將Key保存起來,以此類推。


    30,配置iOS項目的設備系統目標設置:Base SDK和Deployment Target

    Xcode為開發者提供了兩個可配置的設置:第一個是Base SDK,第二個是iOS的Deployment Target。通過配置這兩個參數可定制應用的功能以及可運行的設備和操作系統版本。


    打開配置界面的操作如下:

    1, 打開工程,然后選擇工程導航面板上的工程文件;
    2,在編輯器面板上選擇**TARGETS**,再選擇**Build Settings**選項卡,Base SDK設置通常是這里的第三個選項,Deployment Target在Deployment下,但在這個面板 上尋找設置的最簡單辦法是在搜索條中搜索。


    1. 配置Base SDK設置
    Base SDK,指的是當前編譯所用的SDK 版本。
    可以將值改為“Latest iOS SDK”或者是開發機器上安裝的任意版本的SDK。Base SDK設置會引導編譯器使用該版本的SDK編譯和構建應用,也就是說,它會直接控制應用使用哪些API。默認情況下,Xcode中創建的新工程總是使用最新版本的SDK,而蘋果會處理API的廢棄。除非你有充分的理由,否則你應該使用這個默認值。


    2. 配置Deployment Target設置
    Deployment Target,它控制著運行應用需要的最低操作系統版本。
    如果你將它設成了特定版本,比如5.0,App Store會自動阻止運行早期操作系統的用戶下載或安裝這個應用。要滿足較多用戶的需求,我建議至少向后兼容操作系統的上一個版本。舉個例子,如果iOS 6是最新的版本,那么至少應該支持iOS 5。可以在設置Base SDK所在的Building Settings選項卡中設置Deployment Target。
    如果你使用iOS 6 SDK中可用的功能,又想支持早期版本,可以將Base SDK設置為最新的SDK(iOS 6),而將Deployment Target至少設置為iOS 5。不過,如果你的應用運行在iOS 5設備上,一些框架和功能可能不能用。開發人員的職責就是讓其應用適應這種情況,能夠正確工作而不會崩潰。

    31,ios 真機調試時出現CopyPngFile error問題

    有時我們在模擬器上調試程序,發現沒有問題,到了真機,出現了CopyPngFile Error的錯誤,簡單來說,回想自己是否最近有修改過圖片資源?最常見的現象來自于直接把jpg格式的圖片文件后綴改為png,就會出現這個問題。

    解決辦法,把直接修改后綴的圖片刪除掉,雙擊jpg,使用系統預覽功能,編輯圖片,然后導出為PNG,然后再導入到工程里,這個問題就解決了。


    32,通過系統的鑰匙串訪問,創建Development或Production私鑰證書(Certificates)

    在菜單中依次選擇 證書助理——從證書頒發機構請求證書:


    在打開的窗口輸入電子郵件和常用名稱,并選擇存儲到磁盤以及讓我指定**對信息


    單擊繼續,在打開的窗口設定文件名稱和位置,點擊繼續,**大小選擇2048位,算法選擇RSA


    點擊繼續,則在之前設定的位置生成了.CSR的簽名文件。默認名稱是CertificateSigningRequest.certSigningRequest

    然后在https://developer.apple.com 上傳這個文件就好了,上傳成功后,apple服務器便會生成一個識別本計算機的Development或distribution證書:ios_distribution.cer,點擊下載到電腦上,雙擊就可以自動安裝到鑰匙串了,至此私鑰生成完畢,接下來創建Provisioning Profiles的時候,別忘記勾選上我們自己的Development或是distribution證書:



    32,ios6上傳APP錯誤:iTunes Store operation failed和Archive validation error錯誤

    一般情況下出現此錯誤是因為連接apple服務器出了問題,建議稍后多嘗試幾次,如果一直都不行的話,如下方法:

    1,更換本機IP地址(如果是DHCP),然后重新Validate或Submit,我就是這么成功的;

    2,更換WiFi網絡環境嘗試;

    3,實在不行使用Xcode-Open Developer Tool-Application Loader工具進行上傳,具體使用方法:Build應用程序,生成的APP文件在(Users/Library/Developer/Xcode/DerivedData/APPUUID名稱/Build/Products/Debug-iphoneos/APP.app),壓縮App.app,然后通過Application Loader導入就可以了,驗證流程和Organizer一樣,不過也可能會出現同樣的錯誤提示;http://stackoverflow.com/questions/25800830/archive-validation-error

    4,最后一個辦法,也是終極大法,找MAC下可用的VPN,然后切換VPN網絡(),再嘗試上傳;


    這個WARNING是說,我的APP沒有支持64位,可以在工程Build Settings Architectures設置。


    33, NSDictionary如何判斷是否包含某個key?

       NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@"yang",@"name","man",@"sex", nil];
        if ([dict objectForKey:@"age"]) {
            NSLog(@"字典包含key:age");
        }
        else{
            NSLog(@"字典不包含key:age");
        }

    34,UIButtontitlelabel.text 不起作用?

    button.titlelabel.text=@"name";設置后運行發現該按鈕沒有顯示name,原因是button設置title的同時,還要設置相應的state,如下:

    [button setTitle:@"name" forState:UIControlStateNormal];

    35,如果UIView B為半透明, 如何讓加載上邊的UIView C不透明?

    有一個UIView A, 然后上邊加載了UIView B 并設置Alpha 為0.8左右的半透明, 現在我想在B上邊再加個UIView C 并設置為不透明. 可是無論我設置Alpha 為1也好 還是打了opaque也好 都還是能看到A view上的內容,效果如下:


    解決辦法,先說原理ViewC之所以透明 是因為父視圖的alpha值會影響到子視圖的alpha值 使得子視圖透明,uiview的alpha值會被傳遞,但是color不會被傳遞,所以:

    方法一:UIViewB的透明度不要使用alpha,換成uiviewb.backgroundColor = [UIColor colorWithWhite:0 alpha:0.8] 這樣一樣可以做出透明的效果

    方法二:把ViewC的父視圖改成ViewA(并且添加在ViewB之后),這樣ViewB相當于只是一個背景夾層,它的alpha值并不會影響到ViewC

    效果如下圖:





    版權聲明:本文為博主原創文章,未經博主允許不得轉載。

    版權聲明:本文為iteye_11495原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/iteye_11495/article/details/82607113

    智能推薦

    iOS開發筆記 -- 多國語言適配

    一、前言 二、根據系統語言適配 1、應用名稱適配 2、代碼適配 3、xib/storyboard 適配 三、應用內切換語言 一、前言 項目要求:多國語言適配。 正確姿勢有兩種:1、根據系統的語言設置軟件對應的語言。2、應用內切換語言。 意外:客戶要求 能夠靈活的設置語言,不用重新上架,就能夠讀取對應的語言。上帝發話 就只能做第三種方案:根據接口來讀取翻譯好的字符,然后賦值。所以就做了一個接口,傳語...

    iOS開發筆記 -- 自動化打包

    簡述 工作中經常會用到Xcode打包進行測試,Archive過程中等待時間過長,影響開發效率,由此想到了利用Python腳本進行自動化打包,并上傳至蒲公英。Python腳本地址 一、配置Python開發環境 在Mac OS平臺下,我們比較常用的就是 Homebrew (軟件包管理工具),擁有安裝、搜索、更新等功能,首先我們需要配置Homebrew,然后用Homebrew直接通過命令安裝Python...

    [筆記]機器學習之線性回歸、L1回歸、L2回歸

      線性回歸是機器學習領域里研究最多的算法,至今已有200年研究歷史了。 線性回歸   線性回歸可用一條線表示輸入值X和輸出值Y之間的關系,這條線的斜率的值,也叫系數。最簡單的線性回歸可表示為y=ax+b。機器學習的目的就是給定數據樣本(x,y),利用學習得到a,b。得到a和b后,就可以給定已知的x求出未知的y,這就是機器學習的目的和意思。   進而我們可以推廣到多個變量的情況,求得對于每一個特征...

    兼容sdk7&amp;iOS7的issue解決小片段總結

      ios7新增加的icon尺寸: 76 x 76:Size for iPad 2 and iPad mini (standard resolution) 120 x 120 :Size for iPhone  and iPod touch (high resolution) 152 x 152: Size for iPad and iPad mini (high r...

    IOS開發筆記(五)——IOS AVFoundation,課程設計主題介紹

    中山大學數據科學與計算機學院本科生實驗報告 (2019年春季學期) 一、實驗題目 IOS課程設計主題講述 IOS AVFoundation 二、實現內容 總結三個課程設計主題 AVFoundation簡介 AVPlayer AVAudio AVCapture 完成AVPlayer Demo 三、實驗結果 A.課程設計主題 1. Feeds信息流咨詢APP 參考今日頭條app 功能 多tab展示 U...

    猜你喜歡

    ios7適配--navgationbar遮住下面view的處理

    3down votefavorite   Have you guys stumbled up on this issue ? Basically in iOS 7 Navigation Controller is rendered over the sub-view I navigated to. In iOS 6 view I navigate to is enclosed betwe...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    精品国产乱码久久久久久蜜桃不卡