Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't render multiline text in CocoaList #215

Closed
Innei opened this issue Mar 11, 2021 · 10 comments
Closed

Can't render multiline text in CocoaList #215

Innei opened this issue Mar 11, 2021 · 10 comments
Assignees
Labels
bug Something isn't working sizing-bug

Comments

@Innei
Copy link

Innei commented Mar 11, 2021

Hi, guys. I want to render a very very long text in CocoaList. But it only render one line and text is clipped with .... I find a solution, that add .fixedSize(horizontal: false, vertical: true) on Text, it's working on SwiftUI native List. But not work on CocoaList.

Just like this.

On top of view is CocoaList, bottom of view is List.

image

There is my test code.

 VStack {
            CocoaList(items) { item in
                Text(String(repeating: "\(item.text) ", count: 3))
                    .fixedSize(horizontal: false, vertical: true)
            }

            List(items) {
                item in
                Text(String(repeating: "\(item.text) ", count: 3))
                    .fixedSize(horizontal: false, vertical: true)
            }
        }
@vmanot
Copy link
Member

vmanot commented Mar 11, 2021

I'll check out this bug! SwiftUI unfortunately exposes very little in terms of layout priorities or sizing preferences when writing [UI/NS]ViewRepresentable(s), so fixing this may be impossible to do in a generic fashion. But I will try nonetheless! :)

@vmanot vmanot self-assigned this Mar 11, 2021
@vmanot vmanot added bug Something isn't working sizing-bug labels Mar 11, 2021
@vmanot
Copy link
Member

vmanot commented Apr 1, 2021

Closing this issue for now as I'm not able to reproduce it, could be a SwiftUI hosting controller bug. Could you upload a full sample project if it still persists? Feel free to reopen with the sample project.

@vmanot vmanot closed this as completed Apr 1, 2021
@Innei
Copy link
Author

Innei commented May 4, 2021

Sorry. I didn't check the reply and forgot about it. This is the demo code.

image

import SwiftUI
import SwiftUIX

fileprivate struct Item: Identifiable {
    var id: UUID = UUID()
    var text: String {
        String(repeating: "A very very long text. ", count: 10)
    }
}


struct TestView: View {
    @State var index = 1
    @State fileprivate var items = [Item]()
    var body: some View {
        List(items) {
            item in
            Text(String(repeating: "\(item.text) ", count: 3))
                .fixedSize(horizontal: false, vertical: true)
        }

        .onAppear {
            for _ in 0 ..< 2 {
                items.append(Item())
            }
        }
    }
}

struct TestView2: View {
    @State var index = 1
    @State fileprivate var items = [Item]()
    var body: some View {
        CocoaList(items) { item in
            Text(String(repeating: "\(item.text) ", count: 3))
                .fixedSize(horizontal: false, vertical: true)
        }

        .onAppear {
            for _ in 0 ..< 2 {
                items.append(Item())
            }
        }
    }
}

struct TestView_Previews: PreviewProvider {
    static var previews: some View {
        ZStack {
            TestView()
        }.ignoresSafeArea(.all, edges: .bottom)
        ZStack {
            
            TestView2()
        }.ignoresSafeArea(.all, edges: .bottom)
    }
}

@Innei
Copy link
Author

Innei commented May 4, 2021

Sorry. I didn't check the reply and forgot about it. This is the demo code.

image

import SwiftUI
import SwiftUIX

fileprivate struct Item: Identifiable {
    var id: UUID = UUID()
    var text: String {
        String(repeating: "A very very long text. ", count: 10)
    }
}


struct TestView: View {
    @State var index = 1
    @State fileprivate var items = [Item]()
    var body: some View {
        List(items) {
            item in
            Text(String(repeating: "\(item.text) ", count: 3))
                .fixedSize(horizontal: false, vertical: true)
        }

        .onAppear {
            for _ in 0 ..< 2 {
                items.append(Item())
            }
        }
    }
}

struct TestView2: View {
    @State var index = 1
    @State fileprivate var items = [Item]()
    var body: some View {
        CocoaList(items) { item in
            Text(String(repeating: "\(item.text) ", count: 3))
                .fixedSize(horizontal: false, vertical: true)
        }

        .onAppear {
            for _ in 0 ..< 2 {
                items.append(Item())
            }
        }
    }
}

struct TestView_Previews: PreviewProvider {
    static var previews: some View {
        ZStack {
            TestView()
        }.ignoresSafeArea(.all, edges: .bottom)
        ZStack {
            
            TestView2()
        }.ignoresSafeArea(.all, edges: .bottom)
    }
}

And, my xCode version is 12.5, complied target is iOS14.0, complied on macOS 11.3.1.

@Innei
Copy link
Author

Innei commented May 4, 2021

@vmanot I try to change target to iOS 14.5, same as before

@MarcoCount
Copy link

@Innei The fixedSize approach is wrong in my opinion.

@vmanot try this code, it's shorter and better to understand the issue:

import SwiftUI
import SwiftUIX

struct Test: Identifiable {
    let id = UUID()
}
struct ContentView: View {
    var body: some View {
        CocoaList([Test(), Test()]) { number in
            Text("Hello, world loooooooooooooooooooooooooooooooooooooong!")
                .padding()
        }
    }
}

If I had to guess the problem stems from there:

override public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {

I have no idea how to fix this.

Screenshot 2021-05-31 at 19 57 38

@MarcoCount
Copy link

@Innei a possible workaround would be to get the available space with a geometry reader and tell the Text his maximum frame size:

struct Test: Identifiable {
    let id = UUID()
}
struct ContentView: View {
    var body: some View {
        GeometryReader { size in
            CocoaList([Test(), Test()]) { number in
                Text("Hello, world loooooooooooooooooooooooooooooooooooooong!")
                    .frame(maxWidth: size.size.width)
            }
        }
    }
}

I hope that @vmanot can find a proper fix, but in the meantime this issue should be re-opened

@vmanot vmanot reopened this May 31, 2021
@vmanot
Copy link
Member

vmanot commented May 31, 2021

@MarcoCount thanks, I'll take a look into this.

get the available space with a geometry reader and tell the Text his maximum frame size

Multiple layout passes are hard to balance with the performance costs, and unfortunately SwiftUI doesn't give me access to a whole host of methods that are used internally for calculating sizes in a more performant manner. Ideally, I wouldn't even be using UIHostingController (there's no UIHostingView for SwiftUI :/). So while I will try and find time to look at this, it's not super high on the priority list at the moment.

@vmanot vmanot closed this as completed May 31, 2021
@vmanot vmanot reopened this May 31, 2021
@MarcoCount
Copy link

@MarcoCount thanks, I'll take a look into this.

get the available space with a geometry reader and tell the Text his maximum frame size

Multiple layout passes are hard to balance with the performance costs, and unfortunately SwiftUI doesn't give me access to a whole host of methods that are used internally for calculating sizes in a more performant manner. Ideally, I wouldn't even be using UIHostingController (there's no UIHostingView for SwiftUI :/). So while I will try and find time to look at this, it's not super high on the priority list at the moment.

Yes, I perfectly understand.
My comment about the GeometryReader is a good workaround while you find time for the fix.
I honestly can't help more than that there.

@vmanot
Copy link
Member

vmanot commented Jul 9, 2021

Closing as I'm officially marking this out of scope for CocoaList. I've exhausted a wide range of solutions trying to balance the tradeoff between performance and layout magic - sticking with performance here.

@vmanot vmanot closed this as completed Jul 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working sizing-bug
Projects
None yet
Development

No branches or pull requests

3 participants