I'm attempting to adapt UIToolbar
to UIViewRepresentable
to use it within SwiftUI. I'm required to support iOS 13, otherwise I would be using Apple's new toolbar in iOS 14.
So far I have code that displays the toolbar on the screen, however it doesn't extend to the safe area at the bottom of the screen for devices with no home button.
Does anyone have any suggestions or references for complete UIToolbar
implementations in SwiftUI?
Image:
https://i.sstatic.net/Weutp.png
My code:
// TestView.swift
var body: some View {
VStack {
Toolbar(items: [
UIBarButtonItem(
title: "Done",
style: .plain,
target: nil,
action: nil
])
}
}
// Toolbar.swift
import SwiftUI
import UIKit
import Foundation
struct Toolbar: UIViewRepresentable {
typealias UIViewType = UIToolbar
var items: [UIBarButtonItem]
var toolbar: UIToolbar
init(items: [UIBarButtonItem]) {
self.toolbar = UIToolbar()
self.items = items
}
func makeUIView(context: UIViewRepresentableContext<Toolbar>) -> UIToolbar {
toolbar.setItems(self.items, animated: true)
toolbar.barStyle = UIBarStyle.default
toolbar.sizeToFit()
return toolbar
}
func updateUIView(_ uiView: UIToolbar, context: UIViewRepresentableContext<Toolbar>) {
}
func makeCoordinator() -> Toolbar.Coordinator {
Coordinator(self)
}
final class Coordinator: NSObject, UIToolbarDelegate, UIBarPositioning {
var toolbar: Toolbar
var barPosition: UIBarPosition
init(_ toolbar: Toolbar) {
self.toolbar = toolbar
self.barPosition = .bottom
}
private func position(for: UIToolbar) -> UIBarPosition {
return .bottom
}
}
}
Any UIViewRepresentable
in context of SwiftUI view hierarchy is just a view, so it should be layout by SwiftUI instruments
Here is fixed part (w/o changes in your representable)
Tested with Xcode 11.4 / iOS 13.4
struct DemoToolbarView: View {
var body: some View {
VStack {
Toolbar(items: [
UIBarButtonItem(
title: "Done",
style: .plain,
target: nil,
action: nil)
])
}.frame(maxHeight: .infinity, alignment: .bottom)
.edgesIgnoringSafeArea(.bottom)
}
}