Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save steventroughtonsmith/a380e1290357f41b79f2432fa8f7f91d to your computer and use it in GitHub Desktop.
Save steventroughtonsmith/a380e1290357f41b79f2432fa8f7f91d to your computer and use it in GitHub Desktop.
visionOS Freeform-style bottom toolbar ornament
//
// VTBMainViewController.swift
// VisionToolbar
//
// Created by Steven Troughton-Smith on 21/07/2023.
//
//
import UIKit
import SwiftUI
struct CLPViewWrapper: UIViewRepresentable {
var view: UIView
func makeUIView(context: Context) -> some UIView {
return view
}
func updateUIView(_ uiView: UIViewType, context: Context) {
}
}
class VTBBarButtonItem: UIBarButtonItem {
convenience init(symbolName:String) {
let button = UIButton()
button.configuration = .borderless()
button.setImage(UIImage(systemName: symbolName), for: .normal)
self.init(customView: button)
}
}
class VTBBarDivider: UIView {
override var isOpaque: Bool {
get {
return false
}
set {
}
}
override func setNeedsLayout() {
setNeedsDisplay()
}
override func draw(_ rect: CGRect) {
let lineSize = CGFloat(2)
UIColor.label.setFill()
UIRectFill(CGRect(x: (bounds.width-lineSize)/2, y: 0, width: lineSize, height: bounds.height))
}
// MARK: -
override var intrinsicContentSize: CGSize {
return CGSize(width: 8.0, height: 34.0)
}
override func sizeThatFits(_ size: CGSize) -> CGSize {
return intrinsicContentSize
}
}
final class VTBMainViewController: UIViewController {
let primaryToolbar = UIToolbar()
init() {
super.init(nibName: nil, bundle: nil)
title = "VisionToolbar"
view.backgroundColor = .white
let a = VTBBarButtonItem(symbolName: "arrow.uturn.backward")
let b = VTBBarButtonItem(symbolName: "arrow.uturn.forward")
let c = UIBarButtonItem(customView: VTBBarDivider())
let d = VTBBarButtonItem(symbolName: "pencil")
let e = VTBBarButtonItem(symbolName: "eraser")
let f = VTBBarButtonItem(symbolName: "theatermask.and.paintbrush")
let s = UIBarButtonItem.fixedSpace(8)
let x = UIBarButtonItem.fixedSpace(8)
primaryToolbar.items = [x, a, s, b, .flexibleSpace(), c, s, d, s, e, s, f, x]
primaryToolbar.layoutMargins = .zero
#if os(xrOS)
setupOrnaments()
#endif
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
#if os(xrOS)
override var preferredContainerBackgroundStyle: UIContainerBackgroundStyle {
return .glass
}
func setupOrnaments() {
let ornament = UIHostingOrnament(sceneAlignment:.bottom, contentAlignment:.center) {
CLPViewWrapper(view: primaryToolbar)
.frame(minWidth: 600, maxHeight: 40)
.padding(.vertical)
.glassBackgroundEffect()
}
ornaments = [ornament]
}
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment