Ios 拖动分隔符以调整视图的大小

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 |

实现由UIView组成的界面的最佳方式是什么?UIView由一条线分隔,该线可以调整视图的大小

以最简单的形式,它可以如下所示:

----------------
|              |  
| 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
  • 差不多就是这样。

    我建议其他行为: 1.在线上按住2秒钟
    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