ra1028 / Carbon

🚴 A declarative library for building component-based user interfaces in UITableView and UICollectionView.
https://ra1028.github.io/Carbon
Apache License 2.0
1.33k stars 97 forks source link

Weird behaviour as I scroll up #61

Closed Dimillian closed 4 years ago

Dimillian commented 5 years ago

Hello,

I'm making a fairly complexe UITableView, and I have some weird behaviours. As I scroll down, mostly no problem. As I scroll up I get really weird behaviours, like blank space (missing components?) and wrongly sized component.

Here is two images, one normal and one as I scroll up. IMG_0496 IMG_0495

Here is some code, this is a big project, it would be very hard for me to extract and isolate this code to make a self contain package in order to reproduce it. But maybe something is wrong in my approach.

Here is my datasource

Screenshot 2019-10-23 at 18 41 18

And also the code of one of my component as an example

struct ReadingActivityQuoteComponent: IdentifiableComponent {
    let quote: Quote?
    let isTop: Bool

    var id: String {
        quote?.id ?? "quoteLoading"
    }

    class View: UIView {
        var quote: Quote? {
            didSet {
                render()
            }
        }

        var isTop: Bool = false {
            didSet {
                if isTop {
                    cardView.maskedCorners = [.topLeft, .topRight]
                } else {
                    cardView.maskedCorners = []
                }
            }
        }

        let quoteLabel = QuoteDarkerLeft(frame: .zero)
        let cardView = CardView(frame: .zero)

        init() {
            super.init(frame: CGRect.zero)

            cardView.maskedCorners = []

            quoteLabel.showAnimatedGradientSkeleton()
            quoteLabel.numberOfLines = 0

            addSubview(cardView)
            cardView.addSubview(quoteLabel)

            constrain(self, cardView, quoteLabel) { parent, card, quote in
                card.top == parent.top
                card.left == parent.readableContentGuide.left + 12
                card.right == parent.readableContentGuide.right - 12
                card.bottom == parent.bottom

                quote.top == card.top + 12
                quote.left == card.left + 12
                quote.right == card.right - 12
                quote.bottom == card.bottom - 12
            }
        }

        required init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }

        func render() {
            quoteLabel.hideSkeleton()
            quoteLabel.text = quote?.text
        }
    }

    func renderContent() -> ReadingActivityQuoteComponent.View {
        View()
    }

    func render(in content: ReadingActivityQuoteComponent.View) {
        content.quote = quote
        content.isTop = isTop
    }
}

Coming from a lot of SwiftUI lately, Carbon is really awesome to use in the UIKit world. But I'm having quite some issues right now. Again, I have no idea if my architecture is wrong or if I'm hitting some underlying Carbon or UITableView related bugs. I'm self sizing every component with auto layout using Cartography.

ra1028 commented 5 years ago

Hi @Dimillian ,

Thanks for sharing your codebase and screenshots.

It's hard to me to assert a clear cause from looking your part of code in your large code base. I'm also building a fairly complex UI using Carbon, but I didn't encounter such a strange behaviors. However, I have been reported from Carbon user that encounter similar bugs when use both UITableViewAutomaticDimension and diffing batch update. Please try to use the UITableViewReloadDataUpdater or reducing the use of self-sizing by using referenceSize.

Dimillian commented 5 years ago

Thanks for the answer,

I have a lot of dynamic text and content, so calculating the height manually sound like a step back from self sizing UITableView. But I'll provide reference size to some static components and see if it improves.

The UITableViewReloadDataUpdater didn't helped at all :(

tomosaaan commented 5 years ago

Hi @Dimillian !

I had similar bugs before. As @ra1028 says, the compatibility of diffing update and UITableViewAutomaticDimension is very bad. So , My solution implemented referenceSize using systemLayoutSizeFitting and at the same time disabled UITableViewAutomaticDimension.

Or if you use UICollectionView, you can avoid it by resizing attribute in preferedLayoutAttributesFitting :) As an example, preferedLayoutAttributesFitting used in DataSourceKit Demo

Thank you !