Minimal reproducible example and some comments:
- Simple layout with single button. With console log on tap.
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Spacer()
HStack {
Spacer()
Button {
print("bottom button tap")
} label: {
Text("1234567890")
}
}
}.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
- Inside of view "onAppear" I call "addButton" (UIButton)
import SwiftUI
@main
struct testApp: App {
var body: some Scene {
WindowGroup {
ContentView().onAppear {
TestSDK.shared.addButton()
}
}
}
}
- "addButton" is looking for view controller and view itself. Then adds UIButton inside view.
class TestSDK {
private var button: UIButton?
static let shared: TestSDK = {
let instance = TestSDK()
return instance
}()
func addButton() {
if self.button != nil {
self.removeButton()
}
self.setupButton()
}
func removeButton() {
if let button = self.button {
button.removeFromSuperview()
self.button = nil
}
}
fileprivate func setupButton() {
guard let root = self.keyWindowPresentedController else {
return
}
guard let view = root.view else {
return
}
self.button = UIButton(frame: .zero)
guard let button = self.button else {
return
}
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
button.backgroundColor = .red
view.addSubview(button)
view.bringSubviewToFront(button)
button.translatesAutoresizingMaskIntoConstraints = false
let views = ["button" : button]
let verticalButton = NSLayoutConstraint.constraints(withVisualFormat: "V:|-(>=0@299)-[button(64)]-40-|", options: NSLayoutConstraint.FormatOptions(), metrics: nil, views: views)
let horizontalButton = NSLayoutConstraint.constraints(withVisualFormat: "H:|-(>=0@299)-[button(64)]-20-|", options: NSLayoutConstraint.FormatOptions(), metrics: nil, views: views)
view.addConstraints(verticalButton + horizontalButton)
}
@objc func buttonAction() {
print("top button tap")
}
}
extension TestSDK {
var keyWindow: UIWindow? {
return UIApplication
.shared
.connectedScenes
.flatMap { ($0 as? UIWindowScene)?.windows ?? [] }
.first { $0.isKeyWindow }
}
var keyWindowPresentedController: UIViewController? {
var viewController = self.keyWindow?.rootViewController
if let presentedController = viewController as? UITabBarController {
viewController = presentedController.selectedViewController
}
while let presentedController = viewController?.presentedViewController {
if let presentedController = presentedController as? UITabBarController {
viewController = presentedController.selectedViewController
} else {
viewController = presentedController
}
}
return viewController
}
}
- UIButton has action. But it is not working - once you will try tap UIButton you will see that action from bottom button is called.