UIButton 不调用 ImageView 中的处理函数
UIButton not calling handler function in ImageView
在我的 Swift 应用程序中,我想将后置摄像头对准物体,然后单击一个按钮。在我的视图控制器中,我试图为位于 cameraOverlayView 上的以编程方式放置的按钮拾取 UIButton 按下。
我不需要拍照 - 我只是用相机对准物体,然后单击按钮。
编译为 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()
}
}
post - UIButton not calling event in imageView 中已经有很好的建议,但这对我没有帮助。谢谢
可能要在func buttonAction(sender: UIButton!)
前面加上@IBAction
我查看了其他类似案例的 SO 帖子,发现有一些。 This post does something similar, and the answers recommend setting userInteractionEnabled
on the imageView
. The documentation 还声明 UIImageView
覆盖 userInteractionEnabled
属性 为 false
。
差不多:
imageView.userInteractionEnabled = true
您已经在评论中说过按钮位于视图的顶部,因此这可能是唯一阻止按钮接收触摸事件的因素。
我想我已经破解了,post 如果它对其他人有帮助的话。这 SO post 就是线索。
问题是 UIImagePickerController 上的 cameraOverlay 上的按钮显示 on-screen,但没有注册触摸。正如@Dia Kharrat 在 post 中指出的那样,“覆盖 UIView 的框架不够大。 UIView 的 clipsToBounds 属性 默认设置为 NO,这意味着它的子视图仍然可见,即使它们在父视图的框架之外......本质上,确保你的覆盖框架足够大,或者你的子视图叠加层位于其范围内。我已将按钮放在叠加层外 - 但它仍在显示。
我添加了 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 的帮助。
在我的 Swift 应用程序中,我想将后置摄像头对准物体,然后单击一个按钮。在我的视图控制器中,我试图为位于 cameraOverlayView 上的以编程方式放置的按钮拾取 UIButton 按下。
我不需要拍照 - 我只是用相机对准物体,然后单击按钮。
编译为 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()
}
}
post - UIButton not calling event in imageView 中已经有很好的建议,但这对我没有帮助。谢谢
可能要在func buttonAction(sender: UIButton!)
@IBAction
我查看了其他类似案例的 SO 帖子,发现有一些。 This post does something similar, and the answers recommend setting userInteractionEnabled
on the imageView
. The documentation 还声明 UIImageView
覆盖 userInteractionEnabled
属性 为 false
。
差不多:
imageView.userInteractionEnabled = true
您已经在评论中说过按钮位于视图的顶部,因此这可能是唯一阻止按钮接收触摸事件的因素。
我想我已经破解了,post 如果它对其他人有帮助的话。这 SO post 就是线索。
问题是 UIImagePickerController 上的 cameraOverlay 上的按钮显示 on-screen,但没有注册触摸。正如@Dia Kharrat 在 post 中指出的那样,“覆盖 UIView 的框架不够大。 UIView 的 clipsToBounds 属性 默认设置为 NO,这意味着它的子视图仍然可见,即使它们在父视图的框架之外......本质上,确保你的覆盖框架足够大,或者你的子视图叠加层位于其范围内。我已将按钮放在叠加层外 - 但它仍在显示。
我添加了 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 的帮助。