Yann Bizeul
Yann Bizeul

Reputation: 453

Chain methods with UIViewRepresentable subclass

I'm trying to implement a UITextView using the following UIViewRepresentable

import Foundation
import SwiftUI

struct TextView: UIViewRepresentable {
    @Binding var text: String
    var _editable : Bool = true

    func makeUIView(context: Context) -> UITextView {
        let result = UITextView()
        let font = UIFont(name: "Menlo",size: 18)
        result.font = font

        return result
    }

    func updateUIView(_ uiView: UITextView, context: Context) {
        uiView.text = text
        uiView.isEditable = _editable
    }

    mutating func editable(_ editable: Bool) -> TextView {
        _editable = editable
        return self
    }
}

You will notice the mutating func editable that I would like to use in my SwiftUI struct like this :

        return ZStack(alignment: Alignment.trailing) {
            TextView(text: Binding($note.content)!)
                .editable(true) // <<<< Here
            VStack {
                Text(dateString)
                    .font(.caption)
                    .foregroundColor(Color.gray)
                    .padding(3)
                Spacer()
            }
        }

But the following exception is thrown :

Cannot use mutating member on immutable value: function call returns immutable value

Screenshot

I suspect that UIViewRepresentable isn't mutable, and wondering if there is a way around it

Upvotes: 0

Views: 478

Answers (1)

Sweeper
Sweeper

Reputation: 270733

These "chained methods" are not supposed to be mutating. If you look at the methods that you can chain in the SwiftUI framework, none of them are marked mutating. Quick example.

These methods are supposed to return a new instance of the struct, with some property changed.

i.e. like this:

func editable(_ editable: Bool) -> TextView {
    // This is a new instance of the struct, but _editable is changed to the new value
    TextView(text: $text, _editable: editable) 
}

Upvotes: 2

Related Questions