2013-05-29 23 views
3

實現由UIViews組成的界面的最佳方式是什麼?UIView由一行分隔,並且該行可以調整視圖的大小?拖動分隔符以調整UIViews的大小

在它最簡單的形式,它可能是這樣的:

---------------- 
|    | 
| View A  | 
|    | 
|--------------| < line which can be moved up and down, resizing the views 
|    | 
| View B  | 
|    | 
---------------- 

它可能有更多的看法。

我的第一個想法是讓這條線成爲一個可拖動的UIView,像Touches,根據它的位置調整視圖的大小,但我確定必須有一個更優雅的解決方案。

+0

根據您是否使用自動佈局和約束,或者這是否爲非自動佈局問題(即您支持6.0之前的iOS版本),答案會有所不同。但簡單的想法是創建一個「UIPanGestureRecognizer」,它將根據您拖動到的位置調整圖像的大小。 – Rob

回答

8

首先,定義,檢測是否開始在邊界的姿態,如果手勢的變化,移動所述邊界:

#import <UIKit/UIGestureRecognizerSubclass.h> 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // I use long press gesture recognizer so it's recognized immediately 

    UILongPressGestureRecognizer *gesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; 
    gesture.minimumPressDuration = 0.0; 
    gesture.allowableMovement = CGFLOAT_MAX; 
    gesture.delegate = self; 
    [self.containerView addGestureRecognizer:gesture]; 
} 

- (void)handlePan:(UILongPressGestureRecognizer *)gesture 
{ 
    static NSArray *matches; 
    static CGPoint firstLocation; 

    if (gesture.state == UIGestureRecognizerStateBegan) 
    { 
     firstLocation = [gesture locationInView:gesture.view]; 
     matches = [BorderBeingDragged findBordersBeingDraggedForView:gesture.view fromLocation:firstLocation]; 
     if (!matches) 
     { 
      gesture.state = UIGestureRecognizerStateFailed; 
      return; 
     } 
    } 
    else if (gesture.state == UIGestureRecognizerStateChanged) 
    { 
     CGPoint location = [gesture locationInView:gesture.view]; 
     CGPoint translation = CGPointMake(location.x - firstLocation.x, location.y - firstLocation.y); 
     [BorderBeingDragged dragBorders:matches translation:translation]; 
    } 
} 

// if your subviews are scrollviews, you might need to tell the gesture recognizer 
// to allow simultaneous gestures 

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 
{ 
    return TRUE; 
} 

其次,定義一個BordersBeingDragged的類,它的邊界的檢測和邊界的改變:

typedef enum NSInteger { 
    kBorderTypeNone = 0, 
    kBorderTypeLeft = 1 << 0, 
    kBorderTypeRight = 1 << 1, 
    kBorderTypeTop = 1 << 2, 
    kBorderTypeBottom = 1 << 3 
} BorderType; 

@interface BorderBeingDragged : NSObject 

@property (nonatomic, weak) UIView *view; 
@property (nonatomic) BorderType borderTypes; 
@property (nonatomic) CGRect originalFrame; 

@end 

static CGFloat const kTolerance = 15.0; 

@implementation BorderBeingDragged 

+ (NSArray *)findBordersBeingDraggedForView:(UIView *)view fromLocation:(CGPoint)point 
{ 
    NSMutableArray *matches = nil; 

    for (UIView *subview in view.subviews) 
    { 
     BorderType types = kBorderTypeNone; 
     CGRect frame = subview.frame; 

     // test top and bottom borders 

     if (point.x >= (frame.origin.x - kTolerance) && 
      point.x <= (frame.origin.x + frame.size.width + kTolerance)) 
     { 
      if (point.y >= (frame.origin.y - kTolerance) && point.y <= (frame.origin.y + kTolerance)) 
       types |= kBorderTypeTop; 
      else if (point.y >= (frame.origin.y + frame.size.height - kTolerance) && point.y <= (frame.origin.y + frame.size.height + kTolerance)) 
       types |= kBorderTypeBottom; 
     } 

     // test left and right borders 

     if (point.y >= (frame.origin.y - kTolerance) && 
      point.y <= (frame.origin.y + frame.size.height + kTolerance)) 
     { 
      if (point.x >= (frame.origin.x - kTolerance) && point.x <= (frame.origin.x + kTolerance)) 
       types |= kBorderTypeLeft; 
      else if (point.x >= (frame.origin.x + frame.size.width - kTolerance) && point.x <= (frame.origin.x + frame.size.width + kTolerance)) 
       types |= kBorderTypeRight; 
     } 

     // if we found any borders, add it to our array of matches 

     if (types != kBorderTypeNone) 
     { 
      if (!matches) 
       matches = [NSMutableArray array]; 

      BorderBeingDragged *object = [[BorderBeingDragged alloc] init]; 
      object.borderTypes = types; 
      object.view   = subview; 
      object.originalFrame = frame; 

      [matches addObject:object]; 
     } 
    } 

    return matches; 
} 

+ (void)dragBorders:(NSArray *)matches translation:(CGPoint)translation 
{ 
    for (BorderBeingDragged *object in matches) 
    { 
     CGRect newFrame = object.originalFrame; 

     if (object.borderTypes & kBorderTypeLeft) 
     { 
      newFrame.origin.x += translation.x; 
      newFrame.size.width -= translation.x; 
     } 
     else if (object.borderTypes & kBorderTypeRight) 
     { 
      newFrame.size.width += translation.x; 
     } 

     if (object.borderTypes & kBorderTypeTop) 
     { 
      newFrame.origin.y += translation.y; 
      newFrame.size.height -= translation.y; 
     } 
     else if (object.borderTypes & kBorderTypeBottom) 
     { 
      newFrame.size.height += translation.y; 
     } 

     object.view.frame = newFrame; 
    } 
} 

@end 
+0

謝謝。如果視圖A和B是滾動視圖,這會起作用嗎?或者UILongPressGestureRecognizer在整個容器視圖中是否會干擾滾動視圖的正常動作(滾動和縮放)? – cannyboy

+0

@cannyboy將手勢添加到包含滾動視圖的視圖是有問題的。一種解決方案是允許同時進行手勢操作(就像我修改後的答案)。不過,如果滾動視圖的內容偏移量不是「CGPointMake(0.0,0.0)」,即您已經滾動子視圖,您會得到一些好奇的效果。因此,如果您要調整子視圖的大小,您可能需要嘗試將'contentOffset'設置爲'CGPointMake(0.0,0.0)'。也可能有其他方法。你應該玩弄它。 – Rob

2

你基本上需要使行視圖可拖動,但它並不需要很複雜。

  1. viewAviewBcontainerView
  2. 全景手勢識別器添加到配置爲單點觸摸的containerView及其委託設爲您的控制器。
  3. UIGestureRecognizerDelegate協議實施gestureRecognizerShouldBegin:協議,並只允許它開始,如果觸摸在線視圖附近。
  4. 在手勢處理機獲得在containerView觸摸位置,並設置線視圖位置和框架viewAviewB

這幾乎是它。

1

我建議其他行爲: 1.按住上線 2.2秒顯得有些ImageView的,你將拖累

0

最簡單的方法是將手勢識別器添加到您的視圖並根據平移調整它們。

相關問題