IOS開發基礎知識--碎片35

1:iOS視圖控制對象生命週期git

 

init-初始化程序github

viewDidLoad-加載視圖編程

viewWillAppear-UIViewController對象的視圖即將加入窗口時調用;數組

viewDidApper-UIViewController對象的視圖已經加入到窗口時調用;緩存

viewWillDisappear-UIViewController對象的視圖即將消失、被覆蓋或是隱藏時調用;cookie

viewDidDisappear-UIViewController對象的視圖已經消失、被覆蓋或是隱藏時調用;網絡

 

執行時間順序app

15:51:44.811inHyron[483:b903] initless

15:51:54.081inHyron[483:b903] viewDidLoadide

15:51:54.082inHyron[483:b903] viewVillAppear

15:51:54.084 inHyron[483:b903] viewDidAppear

很明顯,先執行init、而後執行viewDidLoad,而後是viewWillAppear最後是viewDidAppear,這樣視圖就建立好了,當視圖消失或者被覆蓋的時候:

15:54:14.557inHyron[483:b903] viewWillDisappear

15:54:14.558inHyron[483:b903] viewDidDisappear

這樣一來視圖就消失了

 

2:初始化一個有默認值實例類

userManager.h文件內容:

#import <Foundation/Foundation.h>

@interface userManager : NSObject

@property(nonatomic,copy)NSString *userName;
@property(nonatomic,copy)NSString *passWord;
@property (assign, nonatomic) NSInteger type;

+(userManager *)userManagerWithType:(NSInteger)type;

-(NSString *)toGetParams;

-(void)configWithObj:(userManager *)userManagerInfo;

@end

userManager.m文件內容:

#import "userManager.h"

@implementation userManager


- (instancetype)init
{
    self = [super init];
    if (self) {
        _userName=@"root";
        _passWord=@"123456";
        _type = 0;
    }
    return self;
}

+(userManager *)userManagerWithType:(NSInteger)type
{
    userManager *myManager=[[userManager alloc]init];
    myManager.type=type;
    return myManager;
}

-(void)configWithObj:(userManager *)userManagerInfo
{
    self.userName=userManagerInfo.userName;
    self.passWord=userManagerInfo.passWord;
    self.type=userManagerInfo.type;
}

-(NSString *)toGetParams
{
    return [NSString stringWithFormat:@"當前用戶:%@ 密碼:%@",self.userName,self.passWord];
}

@end

調用代碼:

userManager *myManager=[userManager userManagerWithType:4];
NSLog(@"用戶信息:%@",myManager.toGetParams);

 

3:NSHTTPCookieStorage(獲取和刪除cookie)

取出cookie

NSArray *cookiesArray = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
NSDictionary *cookieDict = [NSHTTPCookie requestHeaderFieldsWithCookies:cookiesArray];
NSString *cookie = [cookieDict objectForKey:@"Cookie"];
//設置http的header的cookie
[urlRequest setValue:cookie forHTTPHeaderField:@"Cookie」];

刪除cookie

NSArray *cookiesArray = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
for (NSHTTPCookie *cookie in cookiesArray) {
    [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
}

 

4:iOS關於在UITableView中,實現多個cell中不一樣的倒計時實現

//全部剩餘時間數組
NSMutableArray *totalLastTime;
在網絡請求到的全部數據中,根據須要將其中要進行倒計時顯示的數據中的剩餘時間單獨保存出來,若是這裏是全部的數據都須要倒計時,則只須要保存時間便可,若是是有部分數據才須要倒計時,則能夠保存字典,兩個鍵值對分別爲其在UITableView的indexPath和剩餘時間:num默認從0開始
NSDictionary *dic = @{@"indexPath":[NSStrin stringWithFormat:@"%i",num],@"lastTime": order.payLastTime};
 [totalLastTime addObject:dic];
開啓定時器方法:
- (void)startTimer
{
    timer = [NSTimer scheduledTimerWithTimeInterval:1 target:selfselector:@selector(refreshLessTime) userInfo:@"" repeats:YES];
 
若是不添加下面這條語句,在UITableView拖動的時候,會阻塞定時器的調用
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];
 
}

主要的定時器中的方法,在該方法中,遍歷totalLastTime,取出其中保存的lasttime和indexpath,time用來顯示,在顯示完後自減,indexpath表明對應顯示的位置,在一次循環後,將新的time和沒有改變的indexpath重新替換totalLastTime 中對應位置的元素,以此保證每一秒執行時,顯示time都是最新的。
- (void)refreshLessTime
{
    NSUInteger time;
    for (int i = 0; i < totalLastTime.count; i++) {
        time = [[[totalLastTime objectAtIndex:i] objectForKey:@"lastTime"]integerValue];
        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:[[[totalLastTime objectAtIndex:i] objectForKey:@"indexPath"] integerValue]];
        WLServiceOrderTableViewCell *cell = (WLServiceOrderTableViewCell *)[_tableView cellForRowAtIndexPath:indexPath];
        cell.remainingTimeLabel.text = [NSString stringWithFormat:@"剩餘支付時間:%@",[self lessSecondToDay:--time]];
        NSDictionary *dic = @{@"indexPath": [NSStringstringWithFormat:@"%i",indexPath.section],@"lastTime": [NSStringstringWithFormat:@"%i",time]};
        [totalLastTime replaceObjectAtIndex:i withObject:dic];
    }
}

- (NSString *)lessSecondToDay:(NSUInteger)seconds
{
    NSUInteger day  = (NSUInteger)seconds/(24*3600);
    NSUInteger hour = (NSUInteger)(seconds%(24*3600))/3600;
    NSUInteger min  = (NSUInteger)(seconds%(3600))/60;
    NSUInteger second = (NSUInteger)(seconds%60);
    
    NSString *time = [NSString stringWithFormat:@"%lu日%lu小時%lu分鐘%lu秒",(unsigned long)day,(unsigned long)hour,(unsigned long)min,(unsigned long)second];
    return time;
 
}

 

項目中運用中的代碼:

- (void)startTimer
{
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(refreshLessTime) userInfo:@"" repeats:YES];
    
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:UITrackingRunLoopMode];
    
}

- (void)refreshLessTime
{
    NSInteger time;
    for (int i = 0; i < self.totalLastTime.count; i++) {
        time = [[[self.totalLastTime objectAtIndex:i] objectForKey:@"lastTime"]integerValue];
        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:[[[self.totalLastTime objectAtIndex:i] objectForKey:@"indexPath"] integerValue] inSection:0];
        BDFindActivityCell *cell = (BDFindActivityCell *)[_tableView cellForRowAtIndexPath:indexPath];
        if (time==0) {
            [cell setCellData:@"活動中"];
            cell.myLabel.text=@"正在搶單中";
            cell.clockImageView.hidden=YES;
//            [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            --time;
        }
        else if(time>0)
        {
            cell.myLabel.text = [NSString stringWithFormat:@"%@",[self lessSecondToDay:--time]];
        }
        NSDictionary *dic = @{@"indexPath": [NSString stringWithFormat:@"%ld",indexPath.row],@"lastTime": [NSString stringWithFormat:@"%li",time]};
        [self.totalLastTime replaceObjectAtIndex:i withObject:dic];
    }
}

- (NSString *)lessSecondToDay:(NSUInteger)seconds
{
    NSUInteger hour = (NSUInteger)(seconds%(24*3600))/3600;
    NSUInteger min  = (NSUInteger)(seconds%(3600))/60;
    NSUInteger second = (NSUInteger)(seconds%60);
    
    NSString *time = [NSString stringWithFormat:@"去搶單 %02lu:%02lu:%02lu",(unsigned long)hour,(unsigned long)min,(unsigned long)second];
    return time;
    
}

 

5:如何運用Method Swizzling動態插入一些操做

假設工程中有不少ViewController,但有個操做每一個頁面都有,之前都是每一個頁面都去編寫相同的代碼,其實用Method Swizzling就能夠解決這個問題,好比RDVTabBarController這個只在四個首頁才顯示出來,其它頁面都進行隱藏;

a:建立一個擴展類:UIViewController+Swizzle

.h文件的內容:

#import <UIKit/UIKit.h>
#import <objc/runtime.h>
#import "RDVTabBarController.h"

@interface UIViewController (Swizzle)

@end

.m文件的內容:

#import "UIViewController+Swizzle.h"

@implementation UIViewController (Swizzle)

+ (void)load
{
    SEL origSel = @selector(viewDidAppear:);
    SEL swizSel = @selector(swiz_viewDidAppear:);
    [UIViewController swizzleMethods:[self class] originalSelector:origSel swizzledSelector:swizSel];
    
    SEL vcWillAppearSel=@selector(viewWillAppear:);
    SEL swizWillAppearSel=@selector(swiz_viewWillAppear:);
    [UIViewController swizzleMethods:[self class] originalSelector:vcWillAppearSel swizzledSelector:swizWillAppearSel];
}

+ (void)swizzleMethods:(Class)class originalSelector:(SEL)origSel swizzledSelector:(SEL)swizSel
{
    Method origMethod = class_getInstanceMethod(class, origSel);
    Method swizMethod = class_getInstanceMethod(class, swizSel);
    
    //class_addMethod will fail if original method already exists
    BOOL didAddMethod = class_addMethod(class, origSel, method_getImplementation(swizMethod), method_getTypeEncoding(swizMethod));
    if (didAddMethod) {
        class_replaceMethod(class, swizSel, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
    } else {
        //origMethod and swizMethod already exist
        method_exchangeImplementations(origMethod, swizMethod);
    }
}

- (void)swiz_viewDidAppear:(BOOL)animated
{
    //能夠對控制器名稱作過濾 達到過濾哪些是不操做
    NSString *curClassName=NSStringFromClass([self class]);
    if (curClassName.length>0&&([curClassName isEqualToString:@"BDCustomerListViewController"]||[curClassName isEqualToString:@"BDOrdersViewController"]||[curClassName isEqualToString:@"BDDiscoverViewController"]||[curClassName isEqualToString:@"BDMineInfoViewController"])) {
        [self.rdv_tabBarController setTabBarHidden:NO animated:YES];
    }
    //須要注入的代碼寫在此處
    [self swiz_viewDidAppear:animated];
}

-(void)swiz_viewWillAppear:(BOOL)animated
{
    if ([[self.navigationController childViewControllers] count] > 1) {
        [self.rdv_tabBarController setTabBarHidden:YES animated:YES];
    }
    [self swiz_viewWillAppear:animated];
}

@end
說明:+ (void)load 方法是一個類方法,當某個類的代碼被讀到內存後,runtime會給每一個類發送 + (void)load 消息。所以 + (void)load 方法是一個調用時機至關早的方法,並且無論父類仍是子類,其 + (void)load 方法都會被調用到,很適合用來插入swizzling方法

b:調用在main.m引入這個擴展類

#import <UIKit/UIKit.h>

#import "AppDelegate.h"

#import "UIViewController+Swizzle.h"

int main(int argc, char * argv[]) {

    @autoreleasepool {

        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));

    }

 }

 

6:IOS關於UIImageView的拉伸問題

 

指定這4個寬度後 會造成黑色模塊 直白點就是 這塊內容就是拉伸後中間那塊不斷填充的部分

UIImage* img=[UIImage imageNamed:@"2.png"];//原圖
UIEdgeInsets edge=UIEdgeInsetsMake(0, 10, 0,10);
     //UIImageResizingModeStretch:拉伸模式,經過拉伸UIEdgeInsets指定的矩形區域來填充圖片 上下左右都會
     //UIImageResizingModeTile:平鋪模式,經過重複顯示UIEdgeInsets指定的矩形區域來填充圖
img= [img resizableImageWithCapInsets:edge resizingMode:UIImageResizingModeStretch];
self.imageView.image=img;

項目中的運用:
        self.myImageView=[[UIImageView alloc]initWithFrame:CGRectMake(0, 100, 184, 25)];

        UIImage *curImage=[UIImage imageNamed:@"form_no_selected_icon"];

        UIEdgeInsets edge=UIEdgeInsetsMake(0, 40, 0,25);

        curImage= [curImage resizableImageWithCapInsets:edge resizingMode:UIImageResizingModeStretch];

        self.myImageView.image=curImage;

        [self.view addSubview:self.myImageView];

若是隻是左右拉伸就用UIImageResizingModeStretch,關於edge的值左右自個根據實際的大小進行肯定,把以這塊進行拉伸,特別要注意2X跟3X的圖片;

 

7:AppDelegate各個事件及一些相應的通知運用

a 活動-》不活動 使用applicationWillResignActive:/UIApplicationWillResignActiveNotification來「暫停」應用程序的顯示。確保工做中不須要及時的用戶輸入,由於應用程序在一段時間內不會得到任何用戶輸入。

 

 b 不活動-》後臺 使用applicationDidEnterBackground:/UIApplicationDidEnterBackgroundNotification釋放在應用程序處於後臺狀態時不須要保留的任何資源(好比緩存的圖像或者其餘能夠輕鬆加載的數據),或者沒法保存在後臺的任何資源(好比網絡鏈接)。在這裏避免過分的使用內存使用將應用程序的最終的暫停快照更小,從而減少了應用程序從RAM整個清楚的風險。還能夠經過此機會保存任何須要的應用數據,這些數據將有助於用戶在下一次從新啓動時候找到上次離開時的進度。 

 

 c 後臺-》不活動 使用applicationDidBecomeActive:/UIApplicationDidBecomeActiveNotification恢復從後臺狀態切換到不活動狀態時候所執行的任何操做。例如,在這裏能夠從新創建持久網絡鏈接。

  

 d不活動-》活動 使用applicationDidBecomeActive:/UIApplicationDidBecomeActiveNotification恢復從不活動到活動狀態時候所作的任何操做。這個方法和通知在應用程序全新啓動時使用,因此在這裏執行的任何操做也必須在該上下文有效。 注意:在此過分過程當中,系統不會提供大量時間來保存這裏的更改,僅提供5秒的時間。若是超過5秒,應用程序將馬上從內存中清楚並進入未運行狀態!

 

以UIApplicationDidBecomeActiveNotification通知爲例子,在頁面上建立一個通知,並實現其代碼:

@interface FirstViewController ()

@end

@implementation FirstViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor=[UIColor redColor];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(didBecomeActiveNotification:)
                                                 name:UIApplicationDidBecomeActiveNotification
                                               object:nil];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)didBecomeActiveNotification:(NSNotification *)note
{
    NSLog(@"哈哈我進入了");
}

@end

上面執行的時間爲程序運行在這一頁,而後退到後臺,又進入APP到這個頁面進行喚醒,就會執行上面那個didBecomeActiveNotification方法;若是沒在這個頁面,就算喚醒也是不會執行

 

8:Aspects運用它進行面向切面編程

Aspects插件地址:https://github.com/steipete/Aspects

建立一個SwizzleManager類:

.h文件內容:

#import <Foundation/Foundation.h>

#import "Aspects/Aspects.h"



@interface SwizzleManager : NSObject



+ (void)createAllHooks;



@end


.m文件內容:

#import "SwizzleManager.h"

#import <UIKit/UIKit.h>



@implementation SwizzleManager



+ (void)createAllHooks

{

    [UIViewController aspect_hookSelector:@selector(viewDidLoad)

                              withOptions:AspectPositionBefore

                               usingBlock:^(id<AspectInfo> info){

                                   //用戶統計代碼寫在此處

                                   NSLog(@"[ASPECT] inject in class instance:%@", [info instance]);

                               }

                                    error:NULL];

    //other hooks ... goes here

    //...

}



@end



而後在AppDelegate文件:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    //在程序啓動的第一時間內建立

    [SwizzleManager createAllHooks];

    
    return YES;
}
不錯的文章:http://tech.glowing.com/cn/method-swizzling-aop/ 裏面的實例能夠記錄每一個頁面,及每一個按鍵的事件

 9:怎麼改變UITextfield placeholder的顏色和位置?

繼承UITextfield,重寫這個方法

- (void) drawPlaceholderInRect:(CGRect)rect {
    [[UIColor blueColor] setFill];
    [self.placeholder drawInRect:rect withFont:self.font lineBreakMode:UILineBreakModeTailTruncation alignment:self.textAlignment];
}

10:怎麼把tableview裏cell的小對勾的顏色改爲別的顏色?

_mTableView.tintColor = [UIColor redColor];
相關文章
相關標籤/搜索