一個java程序員自學IOS開發之路(八)

2015/11/8數組

Day 34微信

UITabBarControllerapp

UINavigationController相似,UITabBarController也能夠輕鬆地管理多個控制器,輕鬆完成控制器之間的切換,典型例子就是QQ、微信等應用框架

 

UITabBarController的使用步驟函數

初始化UITabBarController學習

設置UIWindow的rootViewController爲UITabBarControlleratom

根據具體狀況,經過addChildViewController方法添加對應個數的子控制器spa

UITabBarController添加控制器的方式有2設計

  • 添加單個子控制器

- (void)addChildViewController:(UIViewController *)childController;對象

 

  • 設置子控制器數組

@property(nonatomic,copy) NSArray *viewControllers;

 

UITabBar

若是UITabBarController有N個子控制器,那麼UITabBar內部就會有N個UITabBarButton做爲子控件

 

若是UITabBarController有4個子控制器,那麼UITabBar的結構大體以下圖所示

 

UITabBarButton裏面顯示什麼內容,由對應子控制器的tabBarItem屬性決定

  • UITabBarItem有如下屬性影響着UITabBarButton的內容
  • 標題文字

@property(nonatomic,copy) NSString *title;

 

  • 圖標

@property(nonatomic,retain) UIImage *image;

 

  • 選中時的圖標

@property(nonatomic,retain) UIImage *selectedImage;

 

  • 提醒數字

@property(nonatomic,copy) NSString *badgeValue;

 

App主流UI框架結構

 

Modal

  • 除了push以外,還有另一種控制器的切換方式,那就是Modal
  • 任何控制器都能經過Modal的形式展現出來
  • Modal的默認效果:新控制器從屏幕的最底部往上鑽,直到蓋住以前的控制器爲止
  • Modal的形式展現控制器

- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion

  • 關閉當初Modal出來的控制器

- (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^)(void))completion;

 

利用主流框架結構仿造了QQ頁面,storyboard設計以下

  

2015/11/9

Day 35

今天開始學習Quartz 2D

Quartz 2D是一個二維繪圖引擎,同時支持iOS和Mac系統

Quartz 2D能完成的工做

繪製圖形 : 線條\三角形\矩形\圓\弧等

繪製文字

繪製\生成圖片(圖像)

讀取\生成PDF

截圖\裁剪圖片

自定義UI控件

… … 

Quartz2DiOS開發中的價值

爲了便於搭建美觀的UI界面,iOS提供了UIKit框架,裏面有各類各樣的UI控件

UILabel:顯示文字

UIImageView:顯示圖片

UIButton:同時顯示圖片和文字(能點擊)

… …

 

利用UIKit框架提供的控件,拼拼湊湊,能搭建和現實一些簡單、常見的UI界面

可是,有些UI界面極其複雜、並且比較個性化,用普通的UI控件沒法實現,這時能夠利用Quartz2D技術將控件內部的結構畫出來,自定義控件的樣子

其實,iOS中大部分控件的內容都是經過Quartz2D畫出來的

所以,Quartz2D在iOS開發中很重要的一個價值是:自定義view(自定義UI控件)

 

圖形上下文

圖形上下文(Graphics Context):是一個CGContextRef類型的數據

圖形上下文的做用

  • 保存繪圖信息、繪圖狀態
  • 決定繪製的輸出目標(繪製到什麼地方去?)

(輸出目標能夠是PDF文件、Bitmap或者顯示器的窗口上)

 

相同的一套繪圖序列,指定不一樣的Graphics Context,就可將相同的圖像繪製到不一樣的目標上

 

Quartz2D提供瞭如下幾種類型的Graphics Context

Bitmap Graphics Context

PDF Graphics Context

Window Graphics Context

Layer Graphics Context

Printer Graphics Context

自定義view

如何利用Quartz2D自定義view?(自定義UI控件)

如何利用Quartz2D繪製東西到view上?

首先,得有圖形上下文,由於它能保存繪圖信息,而且決定着繪製到什麼地方去

其次,那個圖形上下文必須跟view相關聯,才能將內容繪製到view上面

自定義view的步驟

新建一個類,繼承自UIView

實現- (void)drawRect:(CGRect)rect方法,而後在這個方法中

取得跟當前view相關聯的圖形上下文

繪製相應的圖形內容

利用圖形上下文將繪製的全部內容渲染顯示到view上面

爲何要實現drawRect:方法才能繪圖到view上?

由於在drawRect:方法中才能取得跟view相關聯的圖形上下文

 

drawRect:方法在何時被調用?

view第一次顯示到屏幕上時(被加到UIWindow上顯示出來)

調用view的setNeedsDisplay或者setNeedsDisplayInRect:

  • Quartz2D的API是純C語言的
  • Quartz2D的API來自於Core Graphics框架
  • 數據類型和函數基本都以CG做爲前綴

CGContextRef

CGPathRef

CGContextStrokePath(ctx);

……

drawRect:方法中取得上下文後,就能夠繪製東西到view上

View內部有個layer(圖層)屬性,drawRect:方法中取得的是一個Layer Graphics Context,所以,繪製的東西實際上是繪製到view的layer上去了

View之因此能顯示東西,徹底是由於它內部的layer

Quartz2D繪圖的代碼步驟

得到圖形上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();

拼接路徑(下面代碼是搞一條線段)

CGContextMoveToPoint(ctx, 10, 10);

CGContextAddLineToPoint(ctx, 100, 100);

繪製路徑

CGContextStrokePath(ctx); // CGContextFillPath(ctx);

經常使用拼接路徑函數

  • 新建一個起點

void CGContextMoveToPoint(CGContextRef c, CGFloat x, CGFloat y)

  • 添加新的線段到某個點

void CGContextAddLineToPoint(CGContextRef c, CGFloat x, CGFloat y)

  • 添加一個矩形

void CGContextAddRect(CGContextRef c, CGRect rect)

  • 添加一個橢圓

void CGContextAddEllipseInRect(CGContextRef context, CGRect rect)

  • 添加一個圓弧

void CGContextAddArc(CGContextRef c, CGFloat x, CGFloat y,

  CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise)

 

經常使用繪製路徑函數

  • Mode參數決定繪製的模式

void CGContextDrawPath(CGContextRef c, CGPathDrawingMode mode)

  • 繪製空心路徑

void CGContextStrokePath(CGContextRef c)

  • 繪製實心路徑

void CGContextFillPath(CGContextRef c)

提示:通常以CGContextDraw、CGContextStroke、CGContextFill開頭的函數,都是用來繪製路徑的

 

圖形上下文棧操做

  • 將當前的上下文copy一份,保存到棧頂(那個棧叫作」圖形上下文棧」)

void CGContextSaveGState(CGContextRef c)

  • 將棧頂的上下文出棧,替換掉當前的上下文

void CGContextRestoreGState(CGContextRef c)

 

今天練習了一些簡單的線,圖形,另外畫了一顆心

 

代碼以下

    CGContextRef ctx = UIGraphicsGetCurrentContext();

    CGContextSetLineWidth(ctx, 3);

    CGContextSetLineCap(ctx, kCGLineCapRound);

    CGContextSetLineJoin(ctx, kCGLineJoinRound);

    

    CGPoint centerPoint = {170, 200};

    CGFloat r = 66;

    

    CGContextAddArc(ctx, centerPoint.x - r, centerPoint.y, r, -M_PI - M_PI_4, 0, 0);

    CGContextAddArc(ctx, centerPoint.x + r, centerPoint.y, r, -M_PI, M_PI_4, 0);

    double s = sqrt(4 + 2 * sqrt(2));

    CGContextAddLineToPoint(ctx, centerPoint.x, centerPoint.y + r * s);

    CGContextClosePath(ctx);

    CGContextSetRGBFillColor(ctx, 1, 0, 0, 0.5);

    CGContextFillPath(ctx);

 

2015/11/10

Day 36

今天學習了矩陣操做

利用矩陣操做,能讓繪製到上下文中的全部路徑一塊兒發生變化

  • 縮放

void CGContextScaleCTM(CGContextRef c, CGFloat sx, CGFloat sy)

  • 旋轉

void CGContextRotateCTM(CGContextRef c, CGFloat angle)

  • 平移

void CGContextTranslateCTM(CGContextRef c, CGFloat tx, CGFloat ty)

 

Quartz2D的內存管理

使用含有「Create」或「Copy」的函數建立的對象,使用完後必須釋放,不然將致使內存泄露

使用不含有「Create」或「Copy」的函數獲取的對象,則不須要釋放

若是retain了一個對象,再也不使用時,須要將其release掉

可使用Quartz 2D的函數來指定retain和release一個對象。例如,若是建立了一個CGColorSpace對象,則使用函數CGColorSpaceRetain和CGColorSpaceRelease來retain和release對象。

也可使用Core Foundation的CFRetain和CFRelease。注意不能傳遞NULL值給這些函數

圖片水印

  • 有時候,在手機客戶端app中也須要用到水印技術
  • 好比,用戶拍完照片後,能夠在照片上打個水印,標識這個圖片是屬於哪一個用戶的
  • 實現方式:利用Quartz2D,將水印(文字、LOGO)畫到圖片的右下角
  • 核心代碼
  • 開啓一個基於位圖的圖形上下文

void     UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale)

  • 從上下文中取得圖片(UIImage)

UIImage* UIGraphicsGetImageFromCurrentImageContext();

  • 結束基於位圖的圖形上下文

void     UIGraphicsEndImageContext();

圖片裁剪

不少app的頭像,都是圓形的

  • 核心代碼

void CGContextClip(CGContextRef c)

將當前上下所繪製的路徑裁剪出來(超出這個裁剪區域的都不能顯示)

屏幕截圖

  • 核心代碼

- (void)renderInContext:(CGContextRef)ctx;

調用某個view的layer的renderInContext:方法便可

 

畫了一些簡單的圖形

 

 

2015/11/12

Day 37

今天聯繫了一下給圖片作水印,原理很簡單,原圖和水印各是一張圖片,先在圖形上下文畫上原圖再畫上水印圖就好了

核心代碼以下

+ (instancetype)imageWithbg:(NSString *)bg Watermark:(NSString *)logo {

    UIImage *bgImage = [UIImage imageNamed:bg];

    

    UIGraphicsBeginImageContextWithOptions(bgImage.size, NO, 0.0);

    [bgImage drawInRect:CGRectMake(0, 0, bgImage.size.width, bgImage.size.height)];

    

    UIImage *watermarkImage = [UIImage imageNamed:logo];

    CGFloat padding = 100;

    CGFloat watermarkW = 500;

    CGFloat watermarkH = 500;

    CGFloat watermarkX = bgImage.size.width - padding - watermarkW;

    CGFloat watermarkY = bgImage.size.height - padding - watermarkH;

    

    [watermarkImage drawInRect:CGRectMake(watermarkX, watermarkY, watermarkW, watermarkH)];

    

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

    

    UIGraphicsEndImageContext();

    

    return newImage;

}

以下,右下角添加了水印

 

相關文章
相關標籤/搜索