paint-brush
Why I Cannot Add Variable to GeometryReader{} Closure Argumentby@siyang-ren
127 reads

Why I Cannot Add Variable to GeometryReader{} Closure Argument

by [email protected]July 11th, 2020
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

A programmer has been using Javascrift for the past two years. He wants to use a GeometryReader{} to contain a view, so he can decide the position of the view base on the parent container property such as size, coordinates space, ect... But he gets an error like this: "Why I can not write variable inside a closure?" He then encountered another issue, Generic parameter`Content`could not be infered. So, I explicitly specify the arguments to fix this issue.

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - Why I Cannot Add Variable to GeometryReader{} Closure Argument
seanren96@gmail.com HackerNoon profile picture

I want to use a GeometryReader{} to contain a view, so I can decide the position of the view base on the parent container property such as size, coordinates space, ect...

So, I have some code like this:

 GeometryReader {
                    geometry in
                    self.badgeSymbols
                        .scaleEffect(1.0 / 4.0, anchor: .top)
                        .position(x: geometry.size.width / 2.0,
                                  y: (3.0 / 4.0) * geometry.size.height)
                }
GeometryReader {
                    geometry in
                    var width = geometry.size.width ;
                    var height = geometry.size.height;
                    self.badgeSymbols
                        .scaleEffect(1.0 / 4.0, anchor: .top)
                        .position(x: width / 2.0,
                                  y: (3.0 / 4.0) * height)
                }

It should work just fine according to my knowledge.

How ever I get an error like this:

Encounter a strange error, I went to google the answer.

And following is my found:

1. Curly braces`{ ...body...}` after the GeometryReader is a syntax called closure. In this case, we call GeometryReader to initialize a GeometryReader instance. According to the Documentation of GeometryReader by Apple.

When we instantiate a type, and there is only one parameter, this parameter happens to be a function.Type, we can GeometryReader followed by {}function (Closure function).

2. Why I can not write variable inside a closure? Soon I realised I asked the wrong question.

Yes, I can write variable inside a closure.

I was writing a variable inside a return sentence. When there is no return keyword in the statements section, the whole section will be treated as a return statement. I can not write new variable inside the return statement.

So, I added a return keyword to teturn my view.

  GeometryReader {
                    geometry in
                    var width = geometry.size.width ;
                    var height = geometry.size.height;
                    self.badgeSymbols
                        .scaleEffect(1.0 / 4.0, anchor: .top)
                        .position(x: geometry.size.width / 2.0, y: (3.0 / 4.0) * geometry.size.height)
                    return Text("Position:x: \(geometry.size.width / 2.0) y: \((3.0 / 4.0) * geometry.size.height))")
                }

Now I encountered another issue, Generic parameter`Content`could not be infered. So, I explicitly specify the arguments to fix this issue. It goes like this:

GeometryReader<Text> {
                    geometry in
                    var width = geometry.size.width ;
                    var height = geometry.size.height;
                    self.badgeSymbols
                        .scaleEffect(1.0 / 4.0, anchor: .top)
                        .position(x: geometry.size.width / 2.0, y: (3.0 / 4.0) * geometry.size.height)
                    return Text("Position:x: \(geometry.size.width / 2.0) y: \((3.0 / 4.0) * geometry.size.height))")
                }

The reason being that, GeometryReader.Type has a generic parameter defined by Apple developer... It is stated like this:

@frozen struct GeometryReader<Content> where Content : View

Simple Explanation: I provide a type that conforms the View Protocol, the compilation will pass.