Home > other >  How to apply multiple modifier in a function to a given View in SwiftUI?
How to apply multiple modifier in a function to a given View in SwiftUI?

Time:12-04

I have a function with this signature (its funcionality is pretty straightforward I think), the implementation isn't important for us:

extension View {
    func border(edge: Edge, color: Color, width: CGFloat = 1, cornerRadius: CGFloat = 0) -> some View
}

Then I want to extend the functionality of the View, and add an extra function that would call the previous function:

extension View {
    func border(edges: [Edge], color: Color, width: CGFloat = 1, cornerRadius: CGFloat = 0) -> some View
}

But the first idea I have didn't work. In UIKit there wouldn't be a problem, but here I cannot figure it out how can I apply multiple (variable quantity) modifier in a single function.

I tried this:

extension View {
   func border(edges: [Edge], color: Color, width: CGFloat = 1, cornerRadius: CGFloat = 0) -> some View {
        var view = self
        edges.forEach { edge in
            view = view.border(edge: edge, color: color, width: width, cornerRadius: cornerRadius)
        }
        return view
    }
}

It shows me 2 errors:

Cannot assign value of type 'some View' to type 'Self'

Return type of instance method 'border(edges:color:width:cornerRadius:)' requires that 'Self' conform to 'View'

I understand the errors, but I cannot say that let the view variable be a some View (var view: View = self cannot be compiled). How (with what syntax / idea) can I solve this issue?

Edit: here is a full code, which shows the issue:

extension SwiftUI.View {
    // not completed implementation, doesn't matter
    public func border(edge: Edge, color: SwiftUI.Color, width: CGFloat = 1, cornerRadius: CGFloat = 0) -> some SwiftUI.View {
        self
    }

    public func border(edges: [Edge], color: SwiftUI.Color, width: CGFloat = 1, cornerRadius: CGFloat = 0) -> some View {
        var view: SwiftUI.View = self
        edges.forEach { edge in
            view = view.border(edge: edge, color: color, width: width, cornerRadius: cornerRadius)
        }
        return view
    }
}

CodePudding user response:

I would solve this task in reverse order - generic implementation for array and single use as array with one element, like:

extension SwiftUI.View {
    public func border(edge: Edge, color: SwiftUI.Color, width: CGFloat = 1, cornerRadius: CGFloat = 0) -> some SwiftUI.View {
        self.border(edges: [edge], color: color, width: width, cornerRadius: cornerRadius)
    }

    public func border(edges: [Edge], color: SwiftUI.Color, width: CGFloat = 1, cornerRadius: CGFloat = 0) -> some View {
        self  // generic implementation here
    }
}
  • Related