ios - UIButton 失去响应(即无法按下它),可能是因为 CGAffineTransform
问题描述
首先,我认为问题出在 上UIVisualEffectView
,但现在我认为问题出在CGAffineTransform
我用来为openOptionsTooltip()
首先,我在该问题上发现了一个类似的问题(请参阅已接受答案的评论),但在我的情况下,我将按钮添加为 的子视图,而UIVisualEffectView
不是将其添加为按钮子视图。
苹果文档说:
根据所需的效果,效果可能会影响视图后面的分层内容或添加到视觉效果视图的 contentView 的内容。
但是我找不到更好的解释来解释它如何或为什么会影响添加到 contentView 的内容。
- 我正在以编程方式完成所有工作,没有任何 xib。
- 视觉效果视图是一个类似于工具提示的气球,当我触摸 titleView 时会出现。
- 我正在创建该视图
viewDidLoad
并在viewController
. - 创建后,当我单击 titleView 时,我将其添加为 UIWindow 的子视图
这是我的代码:
创建视图的方法:
func createOptionsTooltip(withNamesAndActions options: [(name: String , action: Selector)]){
self.tooltipSize = CGSize(width: 250, height: CGFloat(60*options.count+12))
var optionItens : [UIView] = []
for i in 0..<options.count{
let optionView = UIView(frame: CGRect(x: .zero, y: CGFloat(60*i), width: self.tooltipSize.width, height: 60))
optionView.backgroundColor = .clear
let separatorView = UIView(frame: CGRect(x: .zero, y: 59, width: self.tooltipSize.width, height: 1))
separatorView.backgroundColor = UIColor(white: 0.8, alpha: 0.5)
let button = UIButton(frame: CGRect(x: .zero, y: .zero, width: self.tooltipSize.width, height: 59))
button.setTitle(options[i].name, for: .normal)
button.setTitleColor(self.view.tintColor, for: .normal)
button.addTarget(self, action: options[i].action, for: .touchUpInside)
button.isEnabled = true
button.isUserInteractionEnabled = true
optionView.addSubview(button)
optionView.addSubview(separatorView)
optionView.bringSubviewToFront(button)
optionItens.append(optionView)
}
self.blackOpaqueView = UIView(frame: self.view.bounds)
self.blackOpaqueView.backgroundColor = UIColor.black
self.blackOpaqueView.alpha = 0
let gesture = UITapGestureRecognizer(target: self, action: #selector(ScheduleNavigationController.closeOptionsTooltip))
// blackOpaqueView.addGestureRecognizer(gesture)
self.vwTooltip = UIView(frame: CGRect(origin: CGPoint(x: self.view.frame.midX - self.tooltipSize.width/2, y: self.view.frame.minY+self.navigationBar.frame.size.height+UIApplication.shared.statusBarFrame.height+10), size: CGSize(width: 1, height: 1)))
self.vwTooltip.transform = self.vwTooltip.transform.scaledBy(x: 1, y: 0.01)
self.vwTooltip.isHidden = true
let vwAim = UIVisualEffectView(frame: CGRect(x: self.tooltipSize.width/2 - 6, y: 0, width: 12, height: 10))
let vwBalloon = UIVisualEffectView(frame: CGRect(x: 0, y: vwAim.frame.size.height, width: self.tooltipSize.width, height: CGFloat(60*options.count)))
vwBalloon.cornerRadius = 8
vwBalloon.contentView.isUserInteractionEnabled = true
vwBalloon.isUserInteractionEnabled = true
let bezPath = trianglePathWithCenter(rect: vwAim.frame)
let maskForPath = CAShapeLayer()
maskForPath.path = bezPath.cgPath
vwAim.layer.mask = maskForPath
vwBalloon.effect = UIBlurEffect(style: .prominent)
vwAim.effect = UIBlurEffect(style: .prominent)
for optionView in optionItens{
vwBalloon.contentView.addSubview(optionView)
vwBalloon.bringSubviewToFront(optionView)
}
self.vwTooltip.addSubview(vwBalloon)
self.vwTooltip.addSubview(vwAim)
self.vwTooltip.bringSubviewToFront(vwBalloon)
vwBalloon.bringSubviewToFront(vwBalloon.contentView)
}
我不是在viewDidLoad
那个路上打电话的:
createOptionsTooltip(withNamesAndActions: [("Sair", #selector(ScheduleNavigationController.closeSchedule(_:))), ("Hoje", #selector(ScheduleNavigationController.scrollToToday(_:)))])
我以这种方式打开动画工具提示:
func openOptionsTooltip(){
if let appDelegate = UIApplication.shared.delegate as? AppDelegate{
appDelegate.window?.addSubview(blackOpaqueView)
appDelegate.window?.addSubview(vwTooltip)
appDelegate.window?.bringSubviewToFront(vwTooltip)
UIView.animate(withDuration: 0.2, animations: {
self.blackOpaqueView.alpha = 0.5
}) { _ in
self.vwTooltip.isHidden = false
UIView.animate(withDuration: 0.1, animations: {
self.vwTooltip.transform = self.vwTooltip.transform.scaledBy(x: 1, y: 100)
})
}
}
}
我试过的:
- 使用 . 将层次结构中的按钮及其所有超级视图放在前面
bringSubviewToFront
。(我已经检查过了,按钮前面没有视图) - 更改
isUserInteractEnabled
层次结构中所有按钮的超级视图。(对于 false 和 true) - 更改我将目标添加到按钮的方式,而不使用方法参数。
- 将选择器方法更改为适用于其他目标的任何其他方法,并在
@objc
和之间切换方法@IBOulet
- 将按钮更改为除
UIVisualEffectView
PS:我发现UIVisualEffectView
有 3 个子视图,但显然 contentView 是上面的视图,请参阅打印它的子视图的日志:
▿ 3 elements
- 0 : <_UIVisualEffectBackdropView: 0x102dcd140; frame = (0 0; 250 120); autoresize = W+H; userInteractionEnabled = NO; layer = <UICABackdropLayer: 0x280d1b480>>
- 1 : <_UIVisualEffectSubview: 0x102dcd350; frame = (0 0; 250 120); autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x280d15c80>>
- 2 : <_UIVisualEffectContentView: 0x102dcc940; frame = (0 0; 250 120); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x280d1ace0>>
我不知道是什么阻止了按钮的用户交互
结果如下:
解决方案
我发现了问题:
在调用openOptionsTooltip()
内部的转换后,它并没有调整所有子视图的大小,但它vwTooltp
本身并没有改变它的框架,但是因为它的clipToBounds
属性是假的,所以所有的子视图都显示出来了,但是用户不能访问按钮动作,因为视图尺寸为 1x1。将方法更改为openOptionsTooltip()
:
func openOptionsTooltip(){
if let appDelegate = UIApplication.shared.delegate as? AppDelegate{
appDelegate.window?.addSubview(blackOpaqueView)
appDelegate.window?.addSubview(vwTooltip)
appDelegate.window?.bringSubviewToFront(vwTooltip)
UIView.animate(withDuration: 0.2, delay: 0.0, options: UIView.AnimationOptions.allowUserInteraction, animations:{
self.blackOpaqueView.alpha = 0.5
}) { _ in
self.vwTooltip.isHidden = false
UIView.animate(withDuration: 0.1, delay: 0.0, options: UIView.AnimationOptions.allowUserInteraction, animations:{
self.vwTooltip.transform = self.vwTooltip.transform.translatedBy(x: 1, y: 1)
self.vwTooltip.transform = self.vwTooltip.transform.scaledBy(x: 1, y: 100)
}){ _ in
self.vwTooltip.frame = self.tooltipFrame
}
}
}
}
现在它工作正常。感谢您的回复
推荐阅读
- node.js - 将文件流转换为文件
- reactjs - Shopify Polaris - 自定义布局问题和样式
- awk - 如何在 linux 中使用 awk 或 cat 分隔列
- ruby-on-rails - act_as_state_machine 辅助方法 rails 6
- python-imaging-library - 在简单的 Pillow 模块示例中获取“write() 参数必须是 str,而不是字节”
- c# - EF Core:如何一次插入具有新的多个相关记录的新记录
- r - R会话终止数据丢失
- java - 在每个 Switch-case 后提示用户打印,除了 case:“0 exit”
- python-3.x - 编译的 Python 函数 Executable 不是单个文件并且不运行
- r - 在 df2 中识别 df1 中的元素,然后在 df2 中使用 R 重合的那些行中添加列