【问题标题】:Trouble with solution for programmatically cropping a picture to a square以编程方式将图片裁剪为正方形的解决方案的问题
【发布时间】:2016-07-19 18:24:37
【问题描述】:

我正在尝试编写代码以使相机仅从我在 iPad 上的应用程序拍摄方形照片。我在这里找到了一个从Objective-C翻译成Swift的解决方案,但是在我用代码拍照后,“使用照片”和“重拍”按钮不会响应触摸,除非我将iPad旋转90度并且从横向模式点击按钮。这当然是非常不可取的。任何关于如何修复我的代码的提示都会很棒。

@IBAction func takePicture(sender: UIButton)
{
    let alertController = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet)
    let takePictureAction = UIAlertAction(title: "Take Picture", style: UIAlertActionStyle.Default)
    { (alertAction: UIAlertAction!) -> Void in
        let picker = UIImagePickerController()
        picker.delegate = self
        picker.sourceType = .Camera
        var f: CGRect
        f = picker.view.bounds
        //f.size.width -= picker.navigationBar.bounds.size.width
        f.size.height -= picker.navigationBar.bounds.size.height
        var barHeight: CGFloat
        barHeight = (f.size.height - f.size.width) / 2
        UIGraphicsBeginImageContext(f.size)
        var edgeColor: UIColor
        edgeColor = UIColor(white: 0, alpha: 0.5)
        edgeColor.set()
        UIRectFillUsingBlendMode(CGRectMake(0, 0, f.size.width, barHeight), CGBlendMode.Normal)
        UIRectFillUsingBlendMode(CGRectMake(0, f.size.height - barHeight, f.size.width, barHeight), CGBlendMode.Normal)
        var overlayImage: UIImage
        overlayImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        let overlayIV = UIImageView(frame: f)
        overlayIV.image = overlayImage
        picker.cameraOverlayView?.addSubview(overlayIV)
        self.presentViewController(picker, animated: true, completion: nil)
    }

    let chooseExistingPicture = UIAlertAction(title: "Use Existing", style: UIAlertActionStyle.Default) {(alertAction: UIAlertAction!) -> Void in

        let picker = UIImagePickerController()
        picker.delegate = self
        picker.sourceType = .PhotoLibrary
        self.presentViewController(picker, animated: true, completion: nil)
    }
    alertController.addAction(takePictureAction)
    alertController.addAction(chooseExistingPicture)
    alertController.view.tintColor = UIColor.blackColor()
    presentViewController(alertController, animated: true, completion: nil)
    let presentationController = alertController.popoverPresentationController
    presentationController?.sourceView = self.view
    presentationController?.sourceRect = CGRectMake(330, 210, 330, 210)
}
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
{

    var image = info[UIImagePickerControllerOriginalImage]

    let imageSize = image?.size
    let width = Double((imageSize?.width)!)
    let height = Double((imageSize?.height)!)
    if width != height {
        let newDimension = min(width, height)
        let widthOffset = (width - newDimension) / 2
        let heightOffset = (height - newDimension) / 2
        UIGraphicsBeginImageContextWithOptions(CGSizeMake(CGFloat(newDimension), CGFloat(newDimension)), false, 0.0)
        image?.drawAtPoint(CGPointMake(CGFloat(-widthOffset), CGFloat(-heightOffset)))
        image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
    }
    CustomPicture.image = image as? UIImage;
    dismissViewControllerAnimated(true, completion: nil)
}

【问题讨论】:

    标签: ios swift uiimagepickercontroller


    【解决方案1】:

    你用这条线在整个选择器的顶部放置一个覆盖:

      let overlayIV = UIImageView(frame: f)
    

    因为f 基本上是选择器边界。旋转“修复”它的原因是视图保持这些边界并且不会调整大小(您没有使用任何自动布局),并且您很幸运按钮超出了这些边界。

    所以,以同样的方式调整导航栏的 f 高度:

     f.size.height -= picker.navigationBar.bounds.size.height
    

    您将需要调整按钮(因此您不在顶部)。为 overlayIV 提供背景颜色可能是个好主意,这样您就可以在调试期间看到它。

    另外,您可以使用视图层次调试器:https://developer.apple.com/library/ios/documentation/ToolsLanguages/Conceptual/Xcode_Overview/ExaminingtheViewHierarchy.html

    最后,考虑设置一些布局约束,以便它在旋转时自行调整大小。

    【讨论】:

    • “f.size.height -= picker.navigationBar.bounds.size.height”这一行应该可以解决这个问题。由于出于某种原因,叠加层似乎仍然与按钮有一点重叠,我尝试使用“f.size.height -= 2 * picker.navigationBar.bounds.size.height”并将叠加层背景着色为蓝色。果然,“重拍”和“使用照片”按钮没有被覆盖覆盖,但它们仍然不起作用。虽然这没有意义 - 你说的是有道理的。如果不覆盖按钮,为什么覆盖会阻止按钮使用?
    • 也为视图的父级着色
    • 您可以使用 Xcode 中的视图调试器来弄清楚发生了什么:developer.apple.com/library/ios/documentation/ToolsLanguages/…
    【解决方案2】:

    我发现我的代码有问题,而不是

    picker.cameraOverlayView?.addSubview(overlayIV)
    

    我需要有

    picker.cameraOverlayView = overlayIV
    

    这样就解决了问题。

    【讨论】:

      猜你喜欢
      • 2013-03-22
      • 2012-03-24
      • 2012-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多