iOS14の端末でUITableViewの中身のみをSwiftUIでビューを作成した際にボタンが反応しない問題がありました。(iOS13ではボタンの反応がありましたのでOSのバージョンによって挙動が異なるようです。)
以下の様にボタンのみが配置されているシンプルな画面を作成します。
import UIKit
import SwiftUI
class ViewController: UIViewController {
@IBOutlet private weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
let view = ButtonView()
let hostingController = UIHostingController(rootView: view)
cell.addSubview(hostingController.view)
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
hostingController.view.heightAnchor.constraint(equalToConstant: 320).isActive = true
hostingController.view.bottomAnchor.constraint(equalTo: cell.bottomAnchor, constant: 16).isActive = true
hostingController.view.topAnchor.constraint(equalTo: cell.topAnchor, constant: 16).isActive = true
hostingController.view.leftAnchor.constraint(equalTo: cell.leftAnchor, constant: 16).isActive = true
hostingController.view.rightAnchor.constraint(equalTo: cell.rightAnchor, constant: -16).isActive = true
hostingController.view.centerYAnchor.constraint(equalTo: cell.centerYAnchor).isActive = true
cell.selectionStyle = .none
return cell
}
}
●ButtonView
struct ButtonView: View {
var body: some View {
HStack {
Spacer()
VStack(alignment: .leading) {
Spacer()
Button(action: {
print("タップ")
}) {
Text("ボタン")
.foregroundColor(Color(.blue))
.font(.system(size: 14))
.padding([.leading, .trailing], 20)
.overlay(
RoundedRectangle(cornerRadius: 14)
.strokeBorder(Color(.blue), lineWidth: 1)
)
}
Spacer()
}
Spacer()
}
}
}
「Debug View Hierarchy」で階層を見てみると以下の様になっていました。
ボタンの上にcontentViewが乗っかってしまっています。
これはcell.addSubviewとしているのが問題で、正しくはcell.contentView.addSubviewとしなければなりませんでした。
OSによって挙動が異なるようですが、パッと見では分かりづらいため備忘録として残しておきます。