vankuik.nl

Latest weblog entries

2021-10-20 Generic parameter Destination could not be inferred

Xcode 13.0. If you're banging out SwiftUI code, and you got the following error message:

    Generic parameter 'Destination' could not be inferred

and it'll follow up with the following error as well (if you tried to navigate to a Text view):

    Cannot convert value of type 'Text' to expected argument type '() -> Destination'

then you probably tried to create a NavigationLink and let auto-complete add the following code:

    NavigationLink(tag: Hashable, selection: Binding<Hashable?>, destination: () -> _, label: () -> _)

The solution is to not use the auto-complete version of NavigationLink, but instead use a different sequence of parameters:

    NavigationLink(destination: () -> _, tag: Hashable, selection: Binding<Hashable?>, label: () -> _)

2021-10-19 Constrained extension must be declared on the unspecialized generic type

Did you get the following error message in Swift?

    Constrained extension must be declared on the unspecialized generic type 'Optional' with constraints specified by a 'where' clause

I got that one, and I tried to extend an optional string as follows:

    extension Optional<String> {
        func ifEmpty(_ replacementString: String) -> String? {
            (self ?? "").isEmpty ? replacementString : self
        }
    }

The correct syntax is:

    extension Optional where Wrapped == String {
        func ifEmpty(_ replacementString: String) -> String? {
            (self ?? "").isEmpty ? replacementString : self
        }
    }

It's still painful that it must return an optional. That can be avoided by a static function, which isn't as nice of course :)

2021-09-30 CGRect appendInterpolation

In the category of errors that you google but don't get results.

Suppose you have the following state variable in a SwiftUI view:

    @State private var textFieldFrame1 = CGRect()    

And you want to display that somewhere, as follows:

    Text("Frame of textfield 1 = \(textFieldFrame1)")

You'll get the following compiler error:

    No exact matches in call to instance method 'appendInterpolation'

The solution is as follows:

    Text("Frame of textfield 1 = " + String(describing: self.textFieldFrame1))

2021-03-22 Debugging view sizes

Here's a tip if you wish to show the sizes of views in your SwiftUI previews. Add the following struct to your project.

    struct ViewSizePreferenceReader: View {
        private struct ViewSizePreferenceKey: PreferenceKey {
            typealias Value = [CGSize]
            static var defaultValue: [CGSize] = []
            static func reduce(value: inout [CGSize], nextValue: () -> [CGSize]) {
                value.append(contentsOf: nextValue())
            }
        }
        @Binding var sizeString: String
        var body: some View {
            GeometryReader { (geometry: GeometryProxy) in
                Color.clear
                    .preference(key: ViewSizePreferenceKey.self, value: [geometry.size])
            }
            .onPreferenceChange(ViewSizePreferenceKey.self) { preferences in
                if let size = preferences.first {
                    self.sizeString = String(format: "%.1f x %.1f", size.width, size.height)
                }
            }
        }
    }

Then add a @State variable for the string, and use the above view as a background, as follows. The preview below will show how the Dynamic Type setting influences SF Symbol based images.

    struct ContentView: View {
        @State private var sizeString = "0x0"
        var body: some View {
            VStack {
                Image(systemName: "magnifyingglass")
                    .imageScale(.large)
                    .background(ViewSizePreferenceReader(sizeString: self.$sizeString))
                Text("Size of button: \(self.sizeString)")
            }
        }
    }
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            Group {
                ContentView()
                ContentView()
                    .environment(\.sizeCategory,
                                 .accessibilityLarge)
            }
            .previewLayout(.fixed(width: 414, height: 200))
        }
    }

2021-01-22 Error in SwiftUI Previews part deux

Today Xcode refused to show previews for one view, displaying "Cannot preview this file" on top of the previews canvas.

This time it's showing the error "SomeUnitTest.swift must belong to at least one target in the current scheme in order to use previews". I have the feeling that this error is incorrect and masks a problem elsewhere, because unittests most certainly should not belong to any other target than the test target.

I have been able to temporarily fix the problem as follows:

  • Quit Xcode and simulator
  • Delete the ~/Library/Developer/Xcode/DerivedData folder
  • Start Xcode and simulator
  • Remove all unittests from the project (don't move to trash, simply remove references)
  • Compile the project
  • Add the unittests back to the project

More...

Weblog Archive

Weblog entries 2021

Weblog entries 2020

Weblog entries 2019

Weblog entries 2018

Weblog entries 2017

Weblog entries 2016

Weblog entries 2015

Weblog entries 2014

Weblog entries 2013

Weblog entries 2012

Weblog entries 2011

Weblog entries 2010

Weblog entries 2009

Weblog entries 2008

Weblog entries 2007

Weblog entries 2006

Weblog entries 2005

Weblog entries 2004

All weblog entries

Articles

Articles, chronologically (latest first). This is pretty old stuff.

Scribblings

Not yet finished. Maybe will never be finished. Maybe they'll get deleted. Who knows?

Programming:

System administration:

Others:

Files: