问题描述
实现由以行分隔的UIView组成的接口的最佳方式是什么,该行可以调整视图的大小?
What would be to the best way of implementing an interface which consists of UIViews which are separated by a line, and the line can resize the views?
以最简单的形式,它看起来可能像这样:
In it's simplest form, it could look like this:
----------------
| |
| View A |
| |
|--------------| < line which can be moved up and down, resizing the views
| |
| View B |
| |
----------------
它可能会有更多的视图.
It could have many more views.
我的第一个想法是使该行成为具有以下内容的可拖动UIView:触摸,它会根据其位置调整视图的大小,但我确定必须有一个更优雅的解决方案.
My first thought would be making the line a draggable UIView with something like Touches, which resized the views according to it's position, but I'm sure there must be a more elegant solution.
推荐答案
首先,定义一个手势以检测您是否从边框开始,如果该手势发生更改,则移动所述边框:
First, define a gesture that detects whether you started on a border, and if the gesture changes, moves said borders:
#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
类,该类用于检测边界和更改边界:
Second, define a BordersBeingDragged
class that does the detection of borders and the changing of borders:
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
这篇关于拖动分隔符以调整UIViews的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!