拖动分隔符以调整UIViews的大小

实现由UIViews组成的接口的最佳方法是什么,这些接口由一行分隔,并且该行可以调整视图的大小?

在它最简单的forms,它可能看起来像这样:

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

它可能有更多的观点。

我的第一个想法是使该线成为可拖动的UIView,其中包含类似Touches的东西,根据它的位置调整视图大小,但我确信必须有一个更优雅的解决方案。

首先,定义一个手势,检测您是否在边框上开始,如果手势发生变化,则移动所述边框:

 #import  - (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 

你基本上需要使行视图可拖动,但它不需要复杂。

  1. viewAviewB放入containerView
  2. 将pan手势识别器添加到为单次触摸配置的containerView ,并将其委托设置为控制器。
  3. 实现gestureRecognizerShouldBegin:来自UIGestureRecognizerDelegate协议,只有在线视图附近触摸时才允许它开始。
  4. 在手势处理程序中获取containerView的触摸位置,并为viewAviewB设置线视图位置和帧

这就是它。

我建议其他行为:1。在第2行按住2秒。出现一些你要拖动的imageView

最简单的方法是在视图中添加手势识别器,并根据平移resize。