欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

ios開發(fā)控件傾斜,ios開發(fā)控件傾斜怎么辦

ios 控件怎么以中心向兩邊延伸

這個(gè)分為三大塊,第一快是簡化Binary Data,具體是App Store那邊搞,開發(fā)者不用管,第二個(gè)是Slicing,就是下載程序的時(shí)候會(huì)自動(dòng)下載你圖片組里面符合設(shè)備分辨率的圖片,例如ip6只會(huì)下載x3的圖片。第三個(gè)叫On Demand Resource。就是你可以給你的資源打上標(biāo)簽,然后規(guī)定哪些在程序下載的時(shí)候一同下載的,哪些可以被額外的下載命令觸發(fā),比如一個(gè)大型游戲你可以先讓第一章隨程序下載,然后第二章在檢測到用戶快玩玩完的時(shí)候再下…看起來挺瘦身的,但要是用戶當(dāng)時(shí)沒網(wǎng)絡(luò)怎么辦?

成都創(chuàng)新互聯(lián)公司是一家專業(yè)從事網(wǎng)站制作、成都做網(wǎng)站的網(wǎng)絡(luò)公司。作為專業(yè)的建站公司,成都創(chuàng)新互聯(lián)公司依托的技術(shù)實(shí)力、以及多年的網(wǎng)站運(yùn)營經(jīng)驗(yàn),為您提供專業(yè)的成都網(wǎng)站建設(shè)、營銷型網(wǎng)站建設(shè)及網(wǎng)站設(shè)計(jì)開發(fā)服務(wù)!

如何自定義iOS中的控件

在開發(fā)過程中,有時(shí)候UIKit的標(biāo)準(zhǔn)控件并不能滿足我們的需求,例如你需要一個(gè)控件能支持用戶方便的選擇0-360°之間的一個(gè)角度值,此時(shí)就需要根據(jù)自己的需求自定義控件了。

對于選擇角度值的控件可以這樣實(shí)現(xiàn):創(chuàng)建一個(gè)圓形的滑塊,用戶通過拖動(dòng)手柄操作就能選擇角度值。實(shí)際上這樣的控件在別的一些平臺中你可能看到過,但是在UIKit中并沒有。

本文就實(shí)現(xiàn)一個(gè)選擇角度值的控件來介紹控件的自定義。下面先來看看到底要做成什么樣子:

1. 子類化UIControl

UIControl 是UIView的子類,它又是所有UIKit控件的父類(例如UIButton、UISlider和UISwitch等)。

UIControl的主要作用是創(chuàng)建相應(yīng)的邏輯將action分發(fā)到對應(yīng)的target,另外90%的情況下,它會(huì)根據(jù)自身的狀態(tài)(例如Highlighted, Selected和Disabled等)來繪制用戶界面。

通過UIControl,我們主要管理3個(gè)重要的任務(wù):

繪制用戶界面

跟蹤用戶的操作

Target-Action模式

在本文的圓形滑塊中,我們要做如下一些事情:

定制一個(gè)用戶界面(圓形滑塊本身),通過該界面用戶可以通過手柄進(jìn)行界面交互。用戶的交互操作會(huì)被轉(zhuǎn)換為控件target對應(yīng)的action(控件將滑塊按鈕的frame origin轉(zhuǎn)換為0-360之間的一個(gè)值,并用于target/action上)。

建議在學(xué)習(xí)本文的時(shí)候從文章尾部的連接中下載完整的示例工程。

下面我將從上面列出的3個(gè)重要任務(wù)一一進(jìn)行分解介紹。

這些步驟都是模塊化的,所以如果你對界面的繪制不感興趣,可以跳 繪制用戶界面 ,直接學(xué)習(xí)后面的步驟。

打開工程文件中的 TBCircluarSlider.m 文件。然后開始學(xué)習(xí)下面的內(nèi)容。

1.1 繪制用戶界面

我比較喜歡使用Core Graphics,唯一用到UIKit的就是通過textfield來顯示滑塊的值。

提醒 :此處需要用到一些 Core Graphics 知識,如果你不懂也沒多大關(guān)系,我會(huì)盡量把代碼做詳細(xì)的講解。

我們先來看看控件的不同組成部分,這樣更有利于后面的學(xué)習(xí)。

首先,是用一個(gè) 黑色的圓環(huán) 當(dāng)做滑塊的背景。

可操作區(qū)域(active area) 是一個(gè)從藍(lán)色到紫色的梯度漸變效果。

用戶通過拖拽下面的這個(gè)手柄按鈕來選擇值:

最后,用于顯示選中值的 TextField 。在下一版中,我計(jì)劃讓用戶可以通過鍵盤輸入角度值。

控件界面的繪制主要使用drawRect函數(shù),首選我們需要獲取到當(dāng)前使用的圖形上下文,如下代碼所示:

CGContextRef ctx = UIGraphicsGetCurrentContext();

1.1.1 繪制背景

背景是360°的,所以只要用CGContextAddArc給圖形上下文添加正確的path,并設(shè)置正確的stroke即可。

下面的代碼可以就可以完成背景的繪制:

//Add the arc path

CGContextAddArc(ctx, self.frame.size.width/2, self.frame.size.height/2, radius, 0, M_PI *2, 0);

//Set the stroke colour

[[UIColor blackColor]setStroke];

//set Line width and cap

CGContextSetLineWidth(ctx, TB_BACKGROUND_WIDTH);

CGContextSetLineCap(ctx, kCGLineCapButt);

//draw it!

CGContextDrawPath(ctx, kCGPathStroke);

CGContextArc 函數(shù)的參數(shù)包括圖形上下文,弧度的中心坐標(biāo)點(diǎn),以及半徑(是一個(gè)私有變量),接著是弧度開始和結(jié)束時(shí)的角度(在TBCircularSlider.m文件的頭部可以看到一些關(guān)于數(shù)學(xué)計(jì)算的方法),最后一個(gè)參數(shù)標(biāo)示繪制的方向,0表示逆時(shí)針方向。

接下來的3行的代碼是用來設(shè)置一些信息的,例如顏色和線條寬度等。最后使用 CGContextDrawPath 方法完成背景的繪制。

1.1.2 繪制用戶的可操作區(qū)域

這部分需要利用一點(diǎn)小技巧才行。此處我們繪制一個(gè)線性漸變的掩碼圖片,下面看看原理:

此處掩碼圖片的工作原理是可以看到原始漸變矩形框的一個(gè)孔。

在這里繪制的弧度有一個(gè)陰影,這是創(chuàng)建掩碼圖時(shí)使用了一點(diǎn)模糊的效果。

下面是創(chuàng)建掩碼圖的相關(guān)代碼:

UIGraphicsBeginImageContext(CGSizeMake(320,320));

CGContextRef imageCtx = UIGraphicsGetCurrentContext();

CGContextAddArc(imageCtx, self.frame.size.width/2 , self.frame.size.height/2, radius, 0, ToRad(self.angle), 0);

[[UIColor redColor]set];

//Use shadow to create the Blur effect

CGContextSetShadowWithColor(imageCtx, CGSizeMake(0, 0), self.angle/20, [UIColor blackColor].CGColor);

//define the path

CGContextSetLineWidth(imageCtx, TB_LINE_WIDTH);

CGContextDrawPath(imageCtx, kCGPathStroke);

//save the context content into the image mask

CGImageRef mask = CGBitmapContextCreateImage(UIGraphicsGetCurrentContext());

UIGraphicsEndImageContext();

在上面的代碼中首先創(chuàng)建了一個(gè)圖形上下文,然后設(shè)置了一下陰影。通過 CGContextSetShadowWithColor 方法,我們可以設(shè)置如下內(nèi)容:

上下文

偏移量(此處不需要)

模糊值(該值是通過參數(shù)控制的:使用當(dāng)前的角度除以20,當(dāng)用戶與此控件交互時(shí),以此獲得一個(gè)簡單的動(dòng)畫模糊值)

顏色

接著是根據(jù)當(dāng)前的角度繪制一個(gè)相應(yīng)的弧度。

例如,如果當(dāng)前的角度變量是360°,那么就繪制一個(gè)圓弧,如果是90°,就繪制一個(gè)弧度為90°的一個(gè)弧。最后,利用 CGBitmapContextCreateImage 方法獲取一張圖片(剛剛繪制的弧)。這個(gè)圖片就是我們所需要的掩碼圖了。

裁剪上下文:

現(xiàn)在我們已經(jīng)有一個(gè)漸變的掩碼圖了。接著利用函數(shù) CGContextClipToMask 對上下文進(jìn)行裁剪——給該函數(shù)傳入上面剛剛創(chuàng)建好的掩碼圖。代碼如下所示:

CGContextClipToMask(ctx, self.bounds, mask);

最后我們來繪制漸變效果,代碼如下所示:

//Define the colour steps

CGFloat components[8] = {

0.0, 0.0, 1.0, 1.0, // Start color - Blue

1.0, 0.0, 1.0, 1.0 }; // End color - Violet

CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB();

CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, components, NULL, 2);

//Define the gradient direction

CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));

CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));

//Choose a colour space

CGColorSpaceRelease(baseSpace), baseSpace = NULL;

//Create and Draw the gradient

CGContextDrawLinearGradient(ctx, gradient, startPoint, endPoint, 0);

CGGradientRelease(gradient), gradient = NULL;

繪制漸變效果需要很多處理,不過我們可以將其分為4部分:

定義顏色的變化范圍

定義漸變的方向

選擇顏色空間

創(chuàng)建并繪制漸變

最終的顯示效果(看到漸變矩形框的一部分)要?dú)w功于之前創(chuàng)建的掩碼圖。

另外,為了在背景邊框模擬光線反射,我添加了一些燈光效果。

1.1.3 繪制手柄

下面我們根據(jù)當(dāng)前的角度值,在的正確位置繪制出手柄。

實(shí)際上,在繪制過程中,這一步非常簡單,復(fù)雜一點(diǎn)的就是計(jì)算一下手柄所在的位置。

這里我們需要使用三角函數(shù)將一個(gè) 標(biāo)量值(scalar number) 轉(zhuǎn)換為 CGPoint 。不要擔(dān)心有多復(fù)雜,只需要使用Sin和Cos函數(shù)就可以完成。代碼如下所示:

-(CGPoint)pointFromAngle:(int)angleInt{

//Define the Circle center

CGPoint centerPoint = CGPointMake(self.frame.size.width/2 - TB_LINE_WIDTH/2, self.frame.size.height/2 - TB_LINE_WIDTH/2);

//Define The point position on the circumference

CGPoint result;

result.y = round(centerPoint.y + radius * sin(ToRad(-angleInt))) ;

result.x = round(centerPoint.x + radius * cos(ToRad(-angleInt)));

return result;

}

上面的代碼中,指定一個(gè)角度值,然后計(jì)算出在圓周上面的位置,當(dāng)然,這里需要圓周的中心點(diǎn)和半徑。

使用sin函數(shù)在使用sin函數(shù)時(shí),需要一個(gè)Y坐標(biāo)值,而cos函數(shù)則需要X坐標(biāo)值。

需要注意的是此處每個(gè)函數(shù)返回的值都認(rèn)為半徑為1,所以需要將所得結(jié)果乘以我們指定的半徑大小,并相對于圓周的中心做計(jì)算。

希望下面的公式對你的理解有所幫助:

1

2

point.y = center.y + (radius * sin(angle));

point.x = center.x + (radius * cos(angle));

通過上面的計(jì)算,現(xiàn)在我們已經(jīng)知道手柄的具體位置了,所以,接下來就直接將手柄繪制到指定位置即可,如下代碼所示:

-(void) drawTheHandle:(CGContextRef)ctx{

CGContextSaveGState(ctx);

//I Love shadows

CGContextSetShadowWithColor(ctx, CGSizeMake(0, 0), 3, [UIColor blackColor].CGColor);

//Get the handle position!

CGPoint handleCenter = [self pointFromAngle: self.angle];

//Draw It!

[[UIColor colorWithWhite:1.0 alpha:0.7]set];

CGContextFillEllipseInRect(ctx, CGRectMake(handleCenter.x, handleCenter.y, TB_LINE_WIDTH, TB_LINE_WIDTH));

CGContextRestoreGState(ctx);

}

具體操作步驟如下:

保存當(dāng)前的上下文(當(dāng)在一個(gè)單獨(dú)的函數(shù)中進(jìn)行繪制任務(wù)時(shí),將上下文的狀態(tài)進(jìn)行保存是編程的一個(gè)好習(xí)慣)。

給手柄設(shè)置一些陰影效果

定義手柄的顏色,然后利用 CGContextFillEllipseInRect 將其繪制出來。

我們在drawRect函數(shù)的最后調(diào)用上面這個(gè)方法:

1

[self drawTheHandle:ctx];

至此,我們就完成了繪制部分的任務(wù)。

1.2 跟蹤用戶的操作

在UIControl的子類中,我們可以 override 3個(gè)特殊的方法來提供一個(gè)自定義的跟蹤行為

1.2.1 開始跟蹤

當(dāng)在控件的bound內(nèi)發(fā)生了一個(gè)觸摸事件,首先會(huì)調(diào)用控件的 beginTrackingWithTouch 方法。

我們就看看如何 override 這個(gè)方法吧:

-(BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event{

[super beginTrackingWithTouch:touch withEvent:event];

//We need to track continuously

return YES;

}

該函數(shù)返回的BOOl值決定著:當(dāng)觸摸事件是dragged時(shí),是否需要響應(yīng)。在我們這里的自定義控件中,是需要跟蹤用戶的dragging,所以返回YES。

上面這個(gè)函數(shù)有兩個(gè)參數(shù):touch對象和事件。

1.2.2 持續(xù)跟蹤

在上一個(gè)方法中我們指定了這里的自定義控件需要跟蹤一個(gè)持續(xù)的事件,所以當(dāng)用戶進(jìn)行drag時(shí),會(huì)調(diào)用一個(gè)特殊的方法: continueTrackingWithTouch :

-(BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event

該方法返回的BOOL值標(biāo)示是否繼續(xù)跟蹤touch事件。

通過該方法我們可以根據(jù)touch位置對用戶的操作進(jìn)行過濾。例如,我們可以:僅當(dāng)touch位置與手柄位置相交的時(shí)候才激活控件(activate control)。不過在這里我們的控制邏輯并不是這樣的,我們希望用戶點(diǎn)擊任何位置都能對手柄做出相應(yīng)的位置處理。

本文的該方法負(fù)責(zé)更新手柄的位置(在后面的一節(jié)中會(huì)看到我們把該位置信息傳遞給對應(yīng)的target上)。

對上面這個(gè)方法的override代碼如下所示:

-(BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event{

[super continueTrackingWithTouch:touch withEvent:event];

//Get touch location

CGPoint lastPoint = [touch locationInView:self];

//Use the location to design the Handle

[self movehandle:lastPoint];

//We'll see this function in the next section:

[self sendActionsForControlEvents:UIControlEventValueChanged];

return YES;

}

上面的代碼中,首先利用 locationInView 獲取到touch的位置,然后將該位置傳遞給 moveHandle 方法,該方法會(huì)將傳入的值轉(zhuǎn)換為一個(gè)有效的手柄位置(a valid handle position)。

此處“a valid position”的意思是什么呢?

此控件的手柄只能在背景圓弧定義的邊界范圍內(nèi)做移動(dòng),但是我們不希望強(qiáng)制要求用戶必須在很小的圓弧內(nèi)才可以移動(dòng)手柄,如果非要這樣的話,用戶體驗(yàn)會(huì)非常的糟糕。

moveHandle 的任務(wù)就是負(fù)責(zé)把任意的位置值轉(zhuǎn)變?yōu)槭直梢苿?dòng)的值,另外,另外,在該函數(shù)中,還對指定的滑塊角度值做了轉(zhuǎn)換,代碼如下所示:

-(void)movehandle:(CGPoint)lastPoint{

//Get the center

CGPoint centerPoint = CGPointMake(self.frame.size.width/2,

self.frame.size.height/2);

//Calculate the direction from the center point to an arbitrary position.

float currentAngle = AngleFromNorth(centerPoint,

lastPoint,

NO);

int angleInt = floor(currentAngle);

//Store the new angle

self.angle = 360 - angleInt;

//Update the textfield

_textField.text = [NSString stringWithFormat:@"%d",

self.angle];

//Redraw

[self setNeedsDisplay];

}

上面代碼中,實(shí)際上主要任務(wù)都是在 AngleFromNorth 方法中處理的:根據(jù)兩個(gè)point,就會(huì)返回一個(gè)連接這兩點(diǎn)對應(yīng)的一個(gè)角度關(guān)系, AngleFromNorth 方法的實(shí)現(xiàn)如下所示:

static inline float AngleFromNorth(CGPoint p1, CGPoint p2, BOOL flipped) {

CGPoint v = CGPointMake(p2.x-p1.x,p2.y-p1.y);

float vmag = sqrt(SQR(v.x) + SQR(v.y)), result = 0;

v.x /= vmag;

v.y /= vmag;

double radians = atan2(v.y,v.x);

result = ToDeg(radians);

return (result =0 ? result : result + 360.0);

}

提醒: angleFromNorth 方法并不是我的原創(chuàng),我是直接從蘋果提供的OSX示例clockControl中拿過來用的。

在上面的代碼中,獲得了角度值以后,將其存儲(chǔ)到 angle 中,然后更新一下textfield的值。

接著調(diào)用的 setNeedDisplay 是為了確保 drawRect 被調(diào)用,以盡快在界面上做出相應(yīng)的更新。

1.2.3 結(jié)束跟蹤

當(dāng)跟蹤結(jié)束的時(shí)候,會(huì)調(diào)用下面這個(gè)方法:

-(void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event{

[super endTrackingWithTouch:touch withEvent:event];

}

在本文中,我們并不需要override該方法。如果當(dāng)用戶完成控件的界面操作時(shí),你希望做一些處理,那么該方法會(huì)非常有用。

1.3 Target-Action模式

至此,圓形滑塊控件可以工作了,你可以drag手柄,并能看到textfield中值的改變。

發(fā)送action——控件事件

如果希望自己定制的控件與UIControl行為保持一致,那么當(dāng)控件的值發(fā)生變化時(shí),需要進(jìn)行通知處理:使用 sendActionsForControlEvents 方法,并制定特定的事件類型,值改變對應(yīng)的事件一般是 UIControlEventValueChanged 。

蘋果已經(jīng)預(yù)定義了許多事件類型(Xcode中,在UIControlEventValueChanged上 cmd + 鼠標(biāo)單擊 )。如果你的控件是繼承自UITextField,那么你可能會(huì)對 UIControlEventEdigitingDidBegin 感興趣,如果你要做一個(gè)touch Up action,那么可以使用UIControlTouchUpInside。

如果你注意的話,在本文前部分的continueTrackingWithTouch方法里面,我們調(diào)用了 sendActionsForControlEvents 方法:

[self sendActionsForControlEvents:UIControlEventValueChanged];

這樣處理之后,當(dāng)控件值發(fā)生變化時(shí),每一個(gè)對象(觀察者——注冊該事件)都會(huì)收到響應(yīng)的通知。

ios開發(fā)怎么調(diào)整按鈕中子控件

所以正常的做法應(yīng)該是在initWithFrame:方法中創(chuàng)建子控件,注意此時(shí)子控件有可能只是一個(gè)局部變量,所以想要在layoutSubviews訪問到的話,一般需要?jiǎng)?chuàng)建這個(gè)子控件的對應(yīng)屬性來指向它。

@property (nonatomic, weak) UIButton *button; // 注意這里使用weak就可以,因?yàn)閎utton已經(jīng)被加入到self.view.subviews這個(gè)數(shù)組里。

...

- (instancetype)initWithFrame: (CGRect)frame

{

if (self = [super initWithFrame: frame]) {

UIButton *button = ... // 創(chuàng)建一個(gè)button

[button setTitle: ...] // 設(shè)置button的屬性

[self.view addSubview: button]; // 將button加到view中,并不設(shè)置尺寸

self.button = button; //將self.button指向這個(gè)button保證在layoutSubviews中可以訪問

UILabel *label = ... // 其他的子控件同理

}

}

這樣我們就可以在layoutSubviews中訪問子控件,設(shè)置子控件的尺寸,因?yàn)榇藭r(shí)view的frame已經(jīng)確定。

- (void)layoutSubviews

{

[super layoutSubviews]; // 注意,一定不要忘記調(diào)用父類的layoutSubviews方法!

self.button.frame = ... // 設(shè)置button的frame

self.label.frame = ... // 設(shè)置label的frame

}

經(jīng)過以上的步驟,就可以實(shí)現(xiàn)自定義控件。

你試試看啊

ios屏幕旋轉(zhuǎn)以后控件的尺寸變化有什么規(guī)律嗎?

是有規(guī)律變化的。

IOS開發(fā)針對不同的屏幕尺寸(包括不同設(shè)備以及同設(shè)備的橫豎版)的UI布局退出了AutoLayout功能,基本原理就是:你給控件添加一些提條件(比如,距離頂部多少距離,距離左邊框多少距離,距離右邊框多少距離,本身控件的寬高值,等等條件),當(dāng)屏幕尺寸變化后,系統(tǒng)會(huì)自動(dòng)根據(jù)你設(shè)定的這些條件來修改控件的尺寸以及位置,達(dá)到你想要的顯示效果。

AutoLayout是IOS6推出的,之前關(guān)于適應(yīng)屏幕部分的叫AutoSize,關(guān)于AutoLayou部分有很多的教程,你可以在搜索詳細(xì)了解下。

iOS表格控件開發(fā)

你做過表格頁面的開發(fā)嗎?

在網(wǎng)上看到兩個(gè)實(shí)現(xiàn)demo,可以說是兩種方式實(shí)現(xiàn)的。

大致就是頂部的航標(biāo)題用一個(gè)TopCollectionView封裝實(shí)現(xiàn),底部的表格使用JContentTableView封裝實(shí)現(xiàn),tableViewCell里是一個(gè)collectionView,每一行有一個(gè)collectionView,稍微自己處理下數(shù)據(jù)源還是可以使用的。

大致就是自己封裝了一個(gè)view,視圖由LeftTableView,RightTableView,TopScrollView實(shí)現(xiàn)。

RightTableViewCell里是scrollView,使用的按鈕實(shí)現(xiàn)的表格的效果。看完這個(gè)實(shí)現(xiàn)還是不推薦吧。

暫時(shí)只是學(xué)習(xí)了下實(shí)現(xiàn),后續(xù)有啥問題更新吧~~~

網(wǎng)站名稱:ios開發(fā)控件傾斜,ios開發(fā)控件傾斜怎么辦
文章轉(zhuǎn)載:http://chinadenli.net/article2/dsdigoc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機(jī)電子商務(wù)、靜態(tài)網(wǎng)站網(wǎng)站改版、服務(wù)器托管、域名注冊

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)