Ios 拖动分隔符以调整视图的大小
实现由UIView组成的界面的最佳方式是什么?UIView由一条线分隔,该线可以调整视图的大小 以最简单的形式,它可以如下所示:Ios 拖动分隔符以调整视图的大小,ios,objective-c,uiview,uigesturerecognizer,Ios,Objective C,Uiview,Uigesturerecognizer,实现由UIView组成的界面的最佳方式是什么?UIView由一条线分隔,该线可以调整视图的大小 以最简单的形式,它可以如下所示: ---------------- | | | View A | | | |--------------| < line which can be moved up and down, resizing the views | | | View B |
----------------
| |
| View A |
| |
|--------------| < line which can be moved up and down, resizing the views
| |
| View B |
| |
----------------
----------------
| |
|查看A|
| |
|--------------|<可以上下移动的线,调整视图大小
| |
|视图B|
| |
----------------
它可以有更多的观点
我的第一个想法是让线条成为一个可拖动的UIView,类似这样的东西,可以根据它的位置调整视图的大小,但我相信一定会有一个更优雅的解决方案。您确实需要使线条视图可拖动,但不需要太复杂
viewA
和viewB
放入containerView
containerView
,并将其委托给控制器UIgestureRecognitizerDelegate
协议执行gestureRecognitizerShouldBegin:
,并且仅当触摸线视图附近时才允许开始containerView
中的触摸位置,并设置viewA
和viewB
2.显示您将首先拖动的某个图像视图,定义一个手势,该手势检测您是否从边框开始,如果手势发生变化,则移动所述边框:
#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;
}
最简单的方法是将手势识别器添加到视图中,并根据平移调整它们的大小。答案将根据您是使用自动布局和约束,还是这是一个非自动布局问题(即您支持6.0之前的iOS版本)而有所不同。但简单的想法是创建一个
uipangesturecognizer
,它将根据您拖动到的位置调整图像的大小。谢谢。如果视图A和B是滚动视图,这是否可行?或者整个容器视图上的UILongPress手势识别器是否会干扰ScrollView正常运行(滚动和缩放)的功能?@cannyboy向包含滚动视图的视图添加手势是有问题的。一个解决方案是允许同时使用手势(如我修改后的答案)。但是,如果ScrollView的内容偏移量不是CGPointMake(0.0,0.0)
,即您已经滚动了子视图,那么您会得到一个稍微奇怪的效果。因此,如果要调整子视图的大小,可能需要尝试将contentOffset
设置为CGPointMake(0.0,0.0)
。可能还有其他方法。你应该玩玩它。
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