你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> ios中創建可以拖動的view原理和實現詳解(含代碼)

ios中創建可以拖動的view原理和實現詳解(含代碼)

編輯:IOS開發綜合

有時候我們會需要在界面上拖動view;uiview是繼承於uiresponder的,所以可以響應觸摸相關的事件。

重點是以下一組方法:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event


- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event // 觸摸事件結束,如果你需要自動把view停靠到一個位置,實現這個方法


- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event //外界因素取消touch事件等,如進入電話,進行特別處理


對於最上面兩個方法是必須實現的,後面兩個方法是用來做一些額外的需求或者處理使用,如果只是要實現拖動view可以不實現。


思路1: 創建一個uiview(或者你需要的控件)的子類,在類中實現上述的方法。

思路2:在你相應的viewcontroller中實現上述方法(在viewcontroller中持有你要拖動的view,這樣才能控制它),也能實現類似的目的,但這樣觸摸的范圍就會是整個viewcontroller的view,你需要在touchesBegan進行相應的判斷(從UITouch中可以得到view的相關信息),才能實現固定在小窗口內部的觸摸。

兩種思路都是可行的,根據你實際情況去做選擇,都沒有問題。

以下是代碼(子類方式的簡單實現,你也可以進行相應修改放到viewcontroller中):

@interface TouchEaglView()
@property (assign, nonatomic) CGPoint beginpoint;
@end
@implementation TouchEaglView

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
self.beginpoint = [touch locationInView:self];
[super touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint currentLocation = [touch locationInView:self];
CGRect frame = self.frame;
frame.origin.x += currentLocation.x - self.beginpoint.x;
frame.origin.y += currentLocation.y - self.beginpoint.y;
self.frame = frame;
}


上面的代碼存在一個問題,那就是他的觸摸移動范圍包括了屏幕之外,你會發現你可以把view部分拖動到屏幕外部。那麼我們需要一個高級一些的實現:

注:這個版本是基於viewcontroller的實現,並未子類化view;self.localview是你持有的小窗口,beginpoint需要你在viewcontroller中自己定義

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if (!self.isInView) // 僅當取到touch的view是小窗口時,我們才響應觸控,否則直接return
{
return;
}

UITouch *touch = [touches anyObject];
CGPoint currentPosition = [touch locationInView:self.localView];
//偏移量
float offsetX = currentPosition.x - beginpoint.x;
float offsetY = currentPosition.y - beginpoint.y;
//移動後的中心坐標
self.localView.center = CGPointMake(self.localView.center.x + offsetX, self.localView.center.y + offsetY);

//x軸左右極限坐標
if (self.localView.center.x > (self.localView.superview.frame.size.width-self.localView.frame.size.width/2))
{
CGFloat x = self.localView.superview.frame.size.width-self.localView.frame.size.width/2;
self.localView.center = CGPointMake(x, self.localView.center.y + offsetY);
}
else if (self.localView.center.x < self.localView.frame.size.width/2)
{
CGFloat x = self.localView.frame.size.width/2;
self.localView.center = CGPointMake(x, self.localView.center.y + offsetY);
}

//y軸上下極限坐標
if (self.localView.center.y > (self.localView.superview.frame.size.height-self.localView.frame.size.height/2))
{
CGFloat x = self.localView.center.x;
CGFloat y = self.localView.superview.frame.size.height-self.localView.frame.size.height/2;
self.localView.center = CGPointMake(x, y);
}
else if (self.localView.center.y <= self.localView.frame.size.height/2)
{
CGFloat x = self.localView.center.x;
CGFloat y = self.localView.frame.size.height/2;
self.localView.center = CGPointMake(x, y);
}
}


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if (touch.view.frame.size.width == 120) // 120為小窗口的寬度(簡單起見這裡使用硬編碼示例),用來判斷觸控范圍;僅當取到touch的view是小窗口時,我們才響應觸控
{
self.isInView = YES;
}
else
{
self.isInView = NO;
}
beginpoint = [touch locationInView:self.localView];

[super touchesBegan:touches withEvent:event];
}







  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved