简体   繁体   English

如何围绕sourceRect的角落来寻找Peek和Pop 3D Touch?

[英]How can I round the corners of the sourceRect for Peek and Pop 3D Touch?

In Safari, if you use 3D touch, the sourceRect of the link that is being touched has rounded corners. 在Safari中,如果使用3D触摸,则正在触摸的链接的sourceRect具有圆角。 When I set the source rect in: func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? { 当我将源rect设置为: func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? { func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? { on previewingContext, I can only set previewingContext.sourceRect which doesn't allow me to round the corners, or set a multi corner area. func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? { on previewingContext,我只能设置previewingContext.sourceRect ,它不允许我绕角,或设置多角区域。 How can I do this? 我怎样才能做到这一点?

You can indirectly set round corners to the sourceRect by adding a corner radius to the sourceView's layer. 您可以通过向sourceView图层添加角半径来间接地将圆角设置为sourceRect。 The when you set previewingContext.sourceRect to the sourceView's bounds, the area that stays in focus will also have the rounded corners. 在当您设置previewingContext.sourceRect到sourceView的边界,即停留在重点领域也将有圆角。

Here is an example that uses a pressable UILabel: 以下是使用可压缩UILabel的示例:

class ViewController: UIViewController {

    var previewingContext: UIViewControllerPreviewing?
    let label = UILabel(frame: CGRectMake(150, 250, 100, 50))

    override func viewDidLoad() {
        super.viewDidLoad()

        let background = UIImageView(frame: view.bounds)
        background.image = UIImage(named: "image.jpg")
        view.addSubview(background)

        label.backgroundColor = UIColor.whiteColor()
        label.text = "Press me!"
        label.textAlignment = .Center
        label.layer.cornerRadius = 20
        label.clipsToBounds = true
        label.userInteractionEnabled = true
        view.addSubview(label)

        previewingContext = registerForPreviewingWithDelegate(self, sourceView: label)
    }
}

extension ViewController: UIViewControllerPreviewingDelegate {

    func previewingContext(previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
        previewingContext.sourceRect = label.bounds

        return UIViewController()
    }

    func previewingContext(previewingContext: UIViewControllerPreviewing, commitViewController viewControllerToCommit: UIViewController) {
        showViewController(viewControllerToCommit, sender: self)
    }
}

在此输入图像描述

First of all the sourceView should have a cornerRadius on its layer, indeed the blur effect will have a corner radius only if the layer of the sourceView has one. 首先,sourceView应该在其图层上有一个cornerRadius,实际上只有当sourceView的图层有一个时,模糊效果才会有一个角半径。 Because the sourceView is readonly, it should be set when the registering is made with the method registerForPreviewingWithDelegate:sourceView: . 因为sourceView是只读的,所以当使用方法registerForPreviewingWithDelegate:sourceView:时应该设置它。

As exemple in a collection view with corner radius on its cells, the registering can be made in collectionView:cellForItemAtIndexPath: . 例如,在其单元格上具有角半径的集合视图中,可以在collectionView:cellForItemAtIndexPath: And for security, and as the previewingContext will be checked later, I keep a weak pointer to the previewingContext returned by registerForPreviewingWithDelegate:sourceView: in the cell itself : 为了安全起见,并且稍后将检查registerForPreviewingWithDelegate:sourceView: ,我保留一个弱指针,指向registerForPreviewingWithDelegate:sourceView:返回的registerForPreviewingWithDelegate:sourceView:在单元格本身中:

if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) {
    id previewingContext = [self registerForPreviewingWithDelegate:self sourceView:cell];
    cell.weakPreviewingContext = previewingContext;
}

Then in the method collectionView:didEndDisplayingCell:forItemAtIndexPath: of the UICollectionViewDelegate protocol I made the unregistering like that : 然后在UICollectionViewDelegate协议的方法collectionView:didEndDisplayingCell:forItemAtIndexPath:中,我进行了取消注册:

if (collectionView == self.collectionView) {
    if ([cell isKindOfClass:UserInHomeCollectionCell.class]) {
        [self unregisterForPreviewingWithContext:((UserInHomeCollectionCell*)cell).weakPreviewingContext];
    }
}

Finally in the method previewingContext:viewControllerForLocation: of the UIViewControllerPreviewingDelegate protocol I made the security check like that : 最后在方法previewingContext:viewControllerForLocation: UIViewControllerPreviewingDelegate协议中我做了类似的安全检查:

UserInHomeCollectionCell *cell = (UserInHomeCollectionCell*)[(UIViewController*)previewingContext view];
NSAssert([cell isKindOfClass:UserInHomeCollectionCell.class], @"***** INTERNAL ERROR: Invalid class for retrieved cell %@", cell);
NSAssert([previewingContext isEqual:((UserInHomeCollectionCell*)cell).weakPreviewingContext], @"***** INTERNAL ERROR: Invalid Previewing Context");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM