Use UIViewRepresentable for custom components not working - swiftui

I have written a lot of components in Swift using UIKit. I'd like to use this custom components with SwiftUI now. I create a struct using UIViewRepresentable:
struct MyIcon: UIViewRepresentable {
func makeUIView(context: Context) -> HUIIconView {
return HUIIconView()
}
func updateUIView(_ uiView: UITextView, context: Context) {
}
}
My HUIIconView is defined like this:
#IBDesignable #objc public class HUIIconView: UIView
Xcode gives me the following error:
Type 'MyIcon' does not conform to protocol 'UIViewRepresentable'
This approach works nicely with Apple's own components like UITextView but does not work for custom components.
How can I use my own components with SwiftUI?

Here it is (tested with Xcode 11.4)
#IBDesignable #objc public class HUIIconView: UIView {
}
struct MyIcon: UIViewRepresentable {
func makeUIView(context: Context) -> HUIIconView {
return HUIIconView()
}
func updateUIView(_ uiView: HUIIconView, context: Context) {
}
}

Related

SwiftUI: No ObservableObject of type Y found, where Y is a subclass of an ObservableObject

SwiftUI errors like this appear frequently on StackOverflow:
Thread 1: Fatal error: No ObservableObject of type Foo found. A View.environmentObject(_:) for Foo may be missing as an ancestor of this view.
The answer is always to pass a Foo instance to a view's environmentObject() function. However, this does not appear to work when passing a subclass of Foo to environmentObject().
Foo.swift
class Foo: ObservableObject {
func doSomething() { ... }
}
Bar.swift
class Bar: Foo {
override func doSomething() { ... }
}
Views.swift
struct BrokenView: View {
#EnvironmentObject var foo: Foo
var body: some View { ... }
}
struct WorkingView: View {
#EnvironmentObject var foo: Bar
var body: some View { ... }
}
struct ParentView: View {
var body: some View {
BrokenView().environmentObject(Bar()) // No ObservableObject of type Foo found...
WorkingView().environmentObject(Bar()) // OK
}
}
Is there any way to use ObservableObject subclasses as environment objects?
Here is a solution (tested with Xcode 12.1 / iOS 14.1) - EnvironmentObject matches injection by explicit type.
var body: some View {
BrokenView().environmentObject(Bar() as Foo) // OK
WorkingView().environmentObject(Bar()) // OK
}

Property with type 'some View' cannot override a property with type 'some View'

I would like to override a computed property with the type 'some View' in my subclass to return a different View but I'm getting this odd error:
open class A {
open var oneView: some View { ...
}
public class B : A {
public override var oneView: some View { ...
}
Property with type 'some View' cannot override a property with type
'some View'
How is it done properly?
You can wrap each one in AnyView. It works like so:
open class A {
open var oneView: AnyView {
AnyView(Text("A"))
}
}
public class B: A {
public override var oneView: AnyView {
AnyView(Text("B"))
}
}
If you want to have a VStack inside the view body for example, you just need to make sure to wrap it in AnyView.

How to perform a custom update before render?

I am trying to invoke a mutating method in my View before render, how can I do that?
struct MyView : View {
mutating func update() { ... } // do something here
var body : some View {
self.update() // error, `self` is immutable
...
}
}

What's the difference between selector with a class prefix vs without in Swift?

When I set up notification in Swift 3, I can declare the selector with or without the class prefix. In both cases, the method is an instance method. What's the difference between prefixing the class vs not? What if the selector should be pointing a class method instead?
class Test : UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self,
selector: #selector(fresh), name: .refresh, object: nil)
}
func refresh() {
}
}
vs
class Test : UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self,
selector: #selector(Test.fresh), name: .refresh, object: nil)
}
func refresh() {
}
}

Accessing ViewModel instance

I am pretty new to MVVM and C++ (managed), and am trying to access my viewmodel object outside of the MainPage constructor.
MainPage::MainPage()
{
InitializeComponent();
//Create ViewModel object
ViewModel ^myViewModel;
myViewModel = ref new ViewModel;
}
ref class ViewModel
{
ViewModel::ViewModel() //Constructor
{
//Create array
const size_t SIZE = 6;
Point arr[SIZE];
}
void ViewModel::doDraw()
{
}
void profileDisplay::MainPage::myButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
myViewModel->doDraw();
}
}
Visual Studio Intellisense reports that my myViewModel under my _Click event is undefined. This seems like it would be a basic problem, but I seem to be hung up on it. Any help is much appreciated!