是否可以合并/交叉两个 UIView 而不是让它们重叠?
Is it possible to merge / intersect two UIViews rather than have them overlap?
给定两个 UIViews
,其边框附加了 UIPanGestureRecognizers
:
如果我将左侧的 UIView
拖到右侧的 UIView
上,这是通常的行为:
是否可以让他们在看起来像合并的地方执行下面的行为?:
正在寻找最简单的方法!
您对 "merge" 而不是重叠的要求似乎只是因为边界而存在。如果没有边界,就没有合并的必要;你只是重叠它们。那么问题就变成了如何处理边框。
我在想也许你可以有一个特殊的 UIView 子类(MergingView
?),它可以充当 2 个视图的父级;边框视图和内容视图。现在边框和内容在不同的视图中,"merging" 变得微不足道。
当我们将A
放在B
之上时,我们所要做的就是将A的边框视图和内容视图交给B(因此它们现在是B的子视图),然后发送B 的所有边框视图到后面。
然后可以继续和B合并更多,过程是一样的。
这适合您的用例吗?如果需要,很高兴 post 编码。
一种方法是使用多个 sibling 层和 zPosition
。为了达到你添加两层的效果,一层用于边框,一层用于内容。并且边框层比内容小zPosition
。当然,使用 UIPanGestureRecognizer
.
移动图层
Swift:
import UIKit
class MergingView: UIView {
let borderLayer = CALayer()
let backgroundLayer = CALayer()
override func layoutSubviews() {
super.layoutSubviews()
addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:))))
borderLayer.borderWidth = 5
borderLayer.frame = frame
borderLayer.zPosition = 10
borderLayer.borderColor = UIColor.black.cgColor
superview?.layer.addSublayer(borderLayer)
backgroundLayer.frame = CGRect(x: frame.origin.x + 5, y: frame.origin.y + 5, width: frame.width - 10, height: frame.height - 10)
backgroundLayer.zPosition = 20
backgroundLayer.backgroundColor = UIColor.white.cgColor
superview?.layer.addSublayer(backgroundLayer);
}
@objc func handlePan(_ recognizer: UIPanGestureRecognizer) {
CATransaction.begin()
CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions)
let translation = recognizer.translation(in: self)
frame = self.frame.offsetBy(dx: translation.x, dy: translation.y)
recognizer.setTranslation(CGPoint.zero, in: self)
borderLayer.frame = borderLayer.frame.offsetBy(dx: translation.x, dy: translation.y)
backgroundLayer.frame = backgroundLayer.frame.offsetBy(dx: translation.x, dy: translation.y)
CATransaction.commit()
}
}
Objective-C header:
#import <UIKit/UIKit.h>
@interface MVMergingView : UIView
@end
Objective-C 实施:
#import "MVMergingView.h"
@interface MVMergingView ()
@property (strong) CALayer *borderLayer;
@property (strong) CALayer *backgroundLayer;
@end
@implementation MVMergingView
- (void)layoutSubviews {
[super layoutSubviews];
[self addGestureRecognizer:[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]];
CALayer *borderLayer = [CALayer layer];
borderLayer.borderWidth = 5.f;
borderLayer.frame = self.frame;
borderLayer.zPosition = 10;
borderLayer.borderColor = UIColor.blackColor.CGColor;
self.borderLayer = borderLayer;
[self.superview.layer addSublayer:borderLayer];
CALayer *backgroundLayer = [CALayer layer];
backgroundLayer.frame = CGRectMake(self.frame.origin.x + 5.f, self.frame.origin.y + 5.f, self.frame.size.width - 10, self.frame.size.height - 10);
backgroundLayer.zPosition = 20;
backgroundLayer.backgroundColor = UIColor.whiteColor.CGColor;
self.backgroundLayer = backgroundLayer;
[self.superview.layer addSublayer:backgroundLayer];
}
- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
CGPoint translation = [recognizer translationInView:self];
self.frame = CGRectOffset(self.frame, translation.x, translation.y);
[recognizer setTranslation:CGPointZero inView:self];
self.borderLayer.frame = CGRectOffset(self.borderLayer.frame, translation.x, translation.y);
self.backgroundLayer.frame = CGRectOffset(self.backgroundLayer.frame, translation.x, translation.y);
[CATransaction commit];
}
@end
给定两个 UIViews
,其边框附加了 UIPanGestureRecognizers
:
如果我将左侧的 UIView
拖到右侧的 UIView
上,这是通常的行为:
是否可以让他们在看起来像合并的地方执行下面的行为?
正在寻找最简单的方法!
您对 "merge" 而不是重叠的要求似乎只是因为边界而存在。如果没有边界,就没有合并的必要;你只是重叠它们。那么问题就变成了如何处理边框。
我在想也许你可以有一个特殊的 UIView 子类(MergingView
?),它可以充当 2 个视图的父级;边框视图和内容视图。现在边框和内容在不同的视图中,"merging" 变得微不足道。
当我们将A
放在B
之上时,我们所要做的就是将A的边框视图和内容视图交给B(因此它们现在是B的子视图),然后发送B 的所有边框视图到后面。
然后可以继续和B合并更多,过程是一样的。
这适合您的用例吗?如果需要,很高兴 post 编码。
一种方法是使用多个 sibling 层和 zPosition
。为了达到你添加两层的效果,一层用于边框,一层用于内容。并且边框层比内容小zPosition
。当然,使用 UIPanGestureRecognizer
.
Swift:
import UIKit
class MergingView: UIView {
let borderLayer = CALayer()
let backgroundLayer = CALayer()
override func layoutSubviews() {
super.layoutSubviews()
addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:))))
borderLayer.borderWidth = 5
borderLayer.frame = frame
borderLayer.zPosition = 10
borderLayer.borderColor = UIColor.black.cgColor
superview?.layer.addSublayer(borderLayer)
backgroundLayer.frame = CGRect(x: frame.origin.x + 5, y: frame.origin.y + 5, width: frame.width - 10, height: frame.height - 10)
backgroundLayer.zPosition = 20
backgroundLayer.backgroundColor = UIColor.white.cgColor
superview?.layer.addSublayer(backgroundLayer);
}
@objc func handlePan(_ recognizer: UIPanGestureRecognizer) {
CATransaction.begin()
CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions)
let translation = recognizer.translation(in: self)
frame = self.frame.offsetBy(dx: translation.x, dy: translation.y)
recognizer.setTranslation(CGPoint.zero, in: self)
borderLayer.frame = borderLayer.frame.offsetBy(dx: translation.x, dy: translation.y)
backgroundLayer.frame = backgroundLayer.frame.offsetBy(dx: translation.x, dy: translation.y)
CATransaction.commit()
}
}
Objective-C header:
#import <UIKit/UIKit.h>
@interface MVMergingView : UIView
@end
Objective-C 实施:
#import "MVMergingView.h"
@interface MVMergingView ()
@property (strong) CALayer *borderLayer;
@property (strong) CALayer *backgroundLayer;
@end
@implementation MVMergingView
- (void)layoutSubviews {
[super layoutSubviews];
[self addGestureRecognizer:[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]];
CALayer *borderLayer = [CALayer layer];
borderLayer.borderWidth = 5.f;
borderLayer.frame = self.frame;
borderLayer.zPosition = 10;
borderLayer.borderColor = UIColor.blackColor.CGColor;
self.borderLayer = borderLayer;
[self.superview.layer addSublayer:borderLayer];
CALayer *backgroundLayer = [CALayer layer];
backgroundLayer.frame = CGRectMake(self.frame.origin.x + 5.f, self.frame.origin.y + 5.f, self.frame.size.width - 10, self.frame.size.height - 10);
backgroundLayer.zPosition = 20;
backgroundLayer.backgroundColor = UIColor.whiteColor.CGColor;
self.backgroundLayer = backgroundLayer;
[self.superview.layer addSublayer:backgroundLayer];
}
- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
CGPoint translation = [recognizer translationInView:self];
self.frame = CGRectOffset(self.frame, translation.x, translation.y);
[recognizer setTranslation:CGPointZero inView:self];
self.borderLayer.frame = CGRectOffset(self.borderLayer.frame, translation.x, translation.y);
self.backgroundLayer.frame = CGRectOffset(self.backgroundLayer.frame, translation.x, translation.y);
[CATransaction commit];
}
@end