https://github.com/p-x9/cocoaui
☕️ Obtain and customize UIKit/Cocoa objects from SwiftUI components.
https://github.com/p-x9/cocoaui
cocoa swiftpackage swiftpackagemanager swiftpm swiftui uikit
Last synced: about 1 year ago
JSON representation
☕️ Obtain and customize UIKit/Cocoa objects from SwiftUI components.
- Host: GitHub
- URL: https://github.com/p-x9/cocoaui
- Owner: p-x9
- License: mit
- Created: 2023-04-02T12:42:15.000Z (about 3 years ago)
- Default Branch: main
- Last Pushed: 2023-07-16T14:05:05.000Z (almost 3 years ago)
- Last Synced: 2024-10-11T22:50:28.913Z (over 1 year ago)
- Topics: cocoa, swiftpackage, swiftpackagemanager, swiftpm, swiftui, uikit
- Language: Swift
- Homepage:
- Size: 43.9 KB
- Stars: 34
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# CocoaUI
Obtain and customize UIKit/Cocoa objects from SwiftUI components.
[](https://github.com/p-x9/CocoaUI/issues)
[](https://github.com/p-x9/CocoaUI/network/members)
[](https://github.com/p-x9/CocoaUI/stargazers)
[](https://github.com/p-x9/CocoaUI/)
## Demo
For example, Slider uses UISlider internally.
Therefore, it can be customized by directly referencing the UISlider object as follows.
```swift
Slider(value: $value)
.cocoa { slider in // UISider
slider.setThumbImage(.init(systemName: "swift"), for: .normal)
}
```

## Document
For components conforming to the protocol named `DefaultCocoaViewBridging`, you can get UIKit/Cocoa objects as follows.
`DefaultCocoaViewBridging` gets the UIView object from SwiftUI.View.
In contrast, `DefaultCocoaControllerBridging` gets the UIViewController object.
The CocoaBriding protocol defines a `DefaultCocoaType`.
For example, for Toggle, the DefaultCocoaType is UISwitch(iOS).
It can be handled as follows
```swift
Toggle("Hello", isOn: .constant(true))
.cocoa { `switch` in
`switch`.onTintColor = .red
}
```
### Specify type
However, if the ToggleStyle is set to `Button`, `UIButton` is used internally instead of `UISwitch`.
For such cases, it is also possible to retrieve the data by specifying the type as follows.
```swift
Toggle("Hello", isOn: .constant(true))
.cocoa(for: UIButton.self) { button in
button.layer.borderWidth = 1
}
```
The method of specifying the type is defined in SwiftUI.View's and does not need to conform to the `DefaultCocoaViewBridging` or `DefaultCocoaControllerBridging ` protocols.
If the specified type is not found, the closure will not be called.
### Support additional component
```swift
extension XXView: DefaultCocoaViewBridging { // confirms `DefaultCocoaViewBridging`
public typealias DefaultCocoaViewType = XXCocoaView // UIKit/Cocoa type
}
extension YYView: DefaultCocoaViewControllerBridging { // confirms `DefaultCocoaViewControllerBridging`
public typealias DefaultCocoaControllerType = YYCocoaViewController // UIKit/Cocoa type
}
```
### LifeCycle Event Modifiers
In some View lifecycle events, a modifier is provided to retrieve the obtained UIKit/Cocoa object.
As an example, the following code hides the tabBar on push and redisplays it on pop.
```swift
TabView {
NavigationView {
List(0..<100) { i in
NavigationLink {
Text("Detail: \(i)")
.cocoa(for: CocoaViewController.self) { vc in
print(vc)
}
.onViewWillAppear { vc in
// Hide TabBar
vc?.tabBarController?.tabBar.isHidden = true
}
.onViewWillDisappear { vc in
// Show TabBar
vc?.tabBarController?.tabBar.isHidden = false
}
} label: {
Text("Row: \(i)")
}
}
}
}
```
The following modifiers are available.
- onViewWillAppear
- onViewDidLoad
- onViewWillDisappear
- onViewDidDisAppear
## SwiftUI and Cocoa correspondence table
This may vary depending on the operating system and usage conditions.
|SwiftUI|style|UIKit(iOS)|Cocoa(macOS)|UIKit(tvOS)|
|:----:|:----:|:----:|:----:|:----:|
|ScrollView|-| UIScrollView|NSScrollView|UIScrollView|
|List|-| UICollectionView(>=iOS16) UITableView(=iOS16) UITableView(