ios - UIButton 不调用 ImageView 中的处理函数

标签 ios iphone swift uibutton uiimagepickercontroller

在我的 Swift 应用程序中,我想将后置摄像头指向对象,然后单击一个按钮。在我的 View Controller 中,我试图为以编程方式放置的按钮按下 UIButton,该按钮位于cameraOverlayView 上。

我不需要拍照 - 我只是使用相机指向物体,然后单击按钮。

编译到 iPhone。我似乎要么让相机工作,要么让按钮工作,但不能同时工作。 imagePicker 位于按钮上方并将其隐藏。谁能建议如何让按钮和 imagePicker 一起工作?提前致谢。

import UIKit
import MobileCoreServices

class FirstViewController: UIViewController {

@IBOutlet weak var imageView: UIImageView!
let imagePicker: UIImagePickerController! = UIImagePickerController()

func noCamera() {
    let alertVC = UIAlertController(
        title: "No Camera",
        message: "Sorry, this device has no camera",
        preferredStyle: .Alert)
    let okAction = UIAlertAction(
        title: "OK",
        style:.Default,
        handler: nil)
    alertVC.addAction(okAction)
    presentViewController(
        alertVC,
        animated: true,
        completion: nil)
}

// THIS IS THE FUNCTION I'M TRYING TO CALL
func buttonAction(sender: UIButton!) {
    if sender.tag == 1 {
        print("Button tapped")
        let alertVC = UIAlertController(
            title: "Button pressed",
            message: "Button pressed",
            preferredStyle: .Alert)
        let okAction = UIAlertAction(
            title: "OK",
            style:.Default,
            handler: nil)
        alertVC.addAction(okAction)
        presentViewController(
            alertVC,
            animated: true,
            completion: nil)
    }
}

@IBAction func useCamera(sender: UIButton) { // A SEPARATE STORYBOARD BUTTON IS USED TO CALL THIS INITIALLY
    if (UIImagePickerController.isSourceTypeAvailable(.Camera)) {
        if UIImagePickerController.availableCaptureModesForCameraDevice(.Rear) != nil {
            //Create camera overlay
            let pickerFrame = CGRectMake(
                0,
                UIApplication.sharedApplication().statusBarFrame.size.height,
                imagePicker.view.bounds.width,
                imagePicker.view.bounds.height - imagePicker.navigationBar.bounds.size.height - imagePicker.toolbar.bounds.size.height)

            // Sights
            let sightDiam: CGFloat = 50 // size of sights
            let sightFrame = CGRectMake(
                pickerFrame.width/2 - sightDiam/2,
                pickerFrame.height/2 - sightDiam/2,
                sightDiam,
                sightDiam)
            UIGraphicsBeginImageContext(pickerFrame.size)
            let context = UIGraphicsGetCurrentContext()
            CGContextSaveGState(context)
            CGContextSetLineWidth(context, 2) // linewidth
            CGContextSetStrokeColorWithColor(context, UIColor.yellowColor().CGColor) // colour
            // Outer circle
            CGContextStrokeEllipseInRect(context, sightFrame)
            // Inner dot
            CGContextStrokeEllipseInRect(context, CGRectMake(sightFrame.minX + sightFrame.width/2-1,sightFrame.minY + sightFrame.height/2-1,2,2))

            // Top tick
            CGContextMoveToPoint(context, sightFrame.minX + sightFrame.width/2, sightFrame.minY + 7)
            CGContextAddLineToPoint(context, sightFrame.minX + sightFrame.width/2, sightFrame.minY - 7)
            // Bottom tick
            CGContextMoveToPoint(context, sightFrame.origin.x + sightFrame.width/2, sightFrame.minY + sightFrame.size.height+7)
            CGContextAddLineToPoint(context, sightFrame.origin.x + sightFrame.width/2, sightFrame.minY + sightFrame.size.height-7)
            // Left tick
            CGContextMoveToPoint(context, sightFrame.minX-7, sightFrame.minY + sightFrame.height/2)
            CGContextAddLineToPoint(context, sightFrame.minX+7, sightFrame.minY + sightFrame.height/2)
            // Right tick
            CGContextMoveToPoint(context, sightFrame.minX + sightFrame.width-7, sightFrame.minY + sightFrame.height/2)
            CGContextAddLineToPoint(context, sightFrame.minX + sightFrame.width+7, sightFrame.minY + sightFrame.height/2)
            // Draw
            CGContextStrokePath(context)
            CGContextRestoreGState(context)

            let overlayImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext();
            let overlayView = UIImageView(frame: pickerFrame)
            overlayView.image = overlayImage
            let screenSize = UIScreen.mainScreen().bounds.size
            let aspectRatio:CGFloat = 4.0/3.0
            let scale = screenSize.height/screenSize.width * aspectRatio

            imagePicker.allowsEditing = false
            imagePicker.sourceType = .Camera
            imagePicker.cameraCaptureMode = .Photo
            imagePicker.modalPresentationStyle = .FullScreen
            imagePicker.showsCameraControls = false // keep off
            imagePicker.cameraOverlayView = overlayView
            imagePicker.cameraViewTransform = CGAffineTransformMakeScale(scale, scale);
            overlayView.userInteractionEnabled = true

            // Add Button (programatically)
            let buttonBorder: CGFloat = 30 // size of button
            let buttonHeight: CGFloat = 50 // height of button
            var button: UIButton = UIButton(type: UIButtonType.System) as UIButton
            button.frame = CGRectMake(
                buttonBorder,
                screenSize.height - buttonBorder - buttonHeight,
                screenSize.width - (buttonBorder * 2),
                buttonHeight)
            button.backgroundColor = UIColor.yellowColor()
            button.setTitle("Aim at object", forState: UIControlState.Normal)
            button.tag = 1
            button.addTarget(self, action: "buttonAction:", forControlEvents: .TouchUpInside)
            button.userInteractionEnabled = true
            overlayView.addSubview(button)
            overlayView.bringSubviewToFront(button)
            button.userInteractionEnabled = true
            presentViewController(imagePicker, animated: false,
                completion: {})
            // I WANTED THE BUTTON CLICK ABOVE TO CALL 'buttonAction'
            // BUT THE BUTTON NEVER GETS ACTIVATED - WHY NOT?

        } else {
            noCamera() // no rear camera
        }
    } else {
        noCamera() // no camera
    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

override func viewDidLoad() {
    super.viewDidLoad()
} 
}

帖子中已经有很好的建议 - UIButton not calling event in imageView但这对我没有帮助。谢谢

最佳答案

我想我已经破解了它,如果它对其他人有帮助,我会发布它。这SO post是线索。

问题是 UIImagePickerController 上的 cameraOverlay 上的按钮显示在屏幕上,但没有注册触摸。正如@Dia Kharrat 在那篇文章中指出的那样,“覆盖 UIView 的框架不够大。 UIView 的 clipsToBounds 属性默认设置为 NO,这意味着它的 subview 仍然可见,即使它们在父级框架之外......本质上,确保您的叠加层的框架足够大,或者您的叠加层的 subview 是位于其范围内。我已将按钮放在叠加层之外 - 但它仍在显示。

我添加了 overlayView.clipsToBounds = true 进行测试,按钮在运行时消失了,证明了上面的评论。所以解决方案是将初始选择器框架定义为全屏尺寸,添加代码:

let screenSize = UIScreen.mainScreen().bounds.size // line moved to top of code
let pickerFrame = CGRectMake(0,0,screenSize.width,screenSize.height) // Full screen size

上面的其余代码保持不变。现在 buttonAction 确实被调用了。感谢@TroyT 和@Fr4nc3sc0NL 的帮助。

关于ios - UIButton 不调用 ImageView 中的处理函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34707972/

相关文章:

ios - 隐藏 shareBuilder 弹出窗口并直接在 Objective c 中的 Google+ 中发布

ios - 滑过钢琴键(swift/iOS)

swift - 这是两种不同类型的枚举吗?

iphone - iOS 中的 Core Data Spotlight 集成

iphone - 应用会加载默认屏幕,然后变黑或崩溃

ios - 在 TopViewController 之上显示 ECSlidingViewController

android - 使用 jQuery "swipe"函数导航图像数组

ios - 在没有将 isRemovedOnCompletion 设置为 false 的情况下保留动画的 stokeEnd 更改

ios - ValidationException : Supplied AttributeValue is empty, 必须恰好包含一种受支持的数据类型

iphone - 在输入过程中移动文本字段