freshOS / Stevia

:leaves: Concise Autolayout code
https://freshos.github.io/SteviaDocs/
MIT License
3.38k stars 214 forks source link

I have problem of setting layout #142

Closed oddukgi closed 4 years ago

oddukgi commented 4 years ago

Hello? I set layout. When I print data, resource location change. Does any idea to fix it? layout

Layout Code

PopularStoreView.swift.zip

What I want to make

IMG_5156

s4cha commented 4 years ago

Hi @sunmiya5 So sorry I haven't been able to respond earlier. Have you been able to fix your issue?

oddukgi commented 4 years ago

I didn't.. I want to implement this layout. 🤓

s4cha commented 4 years ago

I am going to take a look and will update you then :)

s4cha commented 4 years ago

Hi @sunmiya5, It's been quite difficult to debug the code since there are many dependencies, missing pieces to make the code actually compile, but here are my remarks/ suggestions.

1 - Do not store result in a cell. store in in the ViewController and render the cell.

You can have a render function in an extension in order to separate the model form the view, for example :

extension PopularStoreView {
    func render(data: StoreList) {
         let storeList = data.storelist
         let storeRate = storeList.states

         lbStoreName.text = storeList.storeInfo.name

         // url-encoding
         let imgURL = storeList.storeInfo.photoURL
         let encoded  = imgURL?.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed)
         let photoURL = URL(string: encoded!)!

         Nuke.loadImage(with: photoURL,
                        options: ImageLoadingOptions(transition: .fadeIn(duration: 0.33)),
                        into: imgStoreView)

         lbRate.text = String(describing: "\(storeRate.rate) (\(storeRate.reviewCount))")          //4.2 (24)
         lbDistance.text = "\(data.distance) km"
         lbDescription.text = storeList.storeInfo.description
         lbDiscount.text = "최대 \(data.maxDiscount)원 할인"
         minCookingTimeView.text = String(data.storelist.storeSettings.minReserveMin)
    }
}

2 - Padding Label

I believe the insets can be done through Autolayout alone, no need for PaddingLabel in my opinion.

3 - lazy vars

I'd personally use classic let over than lazy var. All the "lazy" vars will be called on view construction anyway so there is no real need for "lazy" in this case, excepted the styling part, which I'd rather put in a styling block via the style function.

4 - Use latest Stevia 5.0.0 syntax

Id' use the latest Stevia syntax and function builder syntax.

5 - Simplify styling

lbDescription.style(subtitleLabelStyle(label:)) can be shortened into lbDescription.style(subtitleLabelStyle)

6 - Never use rects in Autolayout.

instead of using

minCookingTimeView.top(stackView.frame.height + 117)

Use an equation instead that will be a NSLayoutConstraint, so updated at runtime.

minCookingTimeView.Top == stackView.Height + 117

6 - Use Layout over Stackviews

While very handy, I believe layout blocks enable us to be very expressive and describe complex layouts without the need for nesting/ using stack vies most of the time.

here is for example your layout:

// MARK: - View Hierarchy
subviews {
    imgStoreView
    lbStoreName
    starIconView
    lbRate
    placeIconView
    lbDistance
    discountIconView
    lbDiscount
    lbDescription
}

// MARK: - Layout
layout {
    16
    |imgStoreView.width(300)| ~ 150
    15
    |lbStoreName
    7
    |starIconView.size(16)⁃lbRate⁃placeIconView.size(16)⁃lbDistance⁃discountIconView.size(16)⁃lbDiscount
    7
    |lbDescription
    13
}    
Screenshot 2020-04-20 at 12 33 11

PS: don't forget layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize for your collectionView layout if you want a dynamically sized cells :)

PS2: I saw you donated for coffee on OpenCollective, this is Very appreciated ❤️ .

Let me know if this helps :)

oddukgi commented 4 years ago

Thank you detailed explain. I applied layout. :)