6

I'm new in SwiftUI, trying to make something like reverse in Android LinearLayoutManager

messagesRecyclerView = view.findViewById(R.id.messagesRecyclerView);

manager = new LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, true); // => true means reverse layout
messagesRecyclerView.setLayoutManager(manager);

in this case everything goes from bottom to top.

Everything useful what I can find is tableview reverse: Load tableview from bottom, scroll up (reverse tableview) (iOS)

//In ViewDidLoad
conversationTableView.transform = CGAffineTransform(rotationAngle: -(CGFloat)(Double.pi));

//In cellForRowAtIndexPath
cell.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi));

but I don't know how to add it into List (seems like it just a wrapper around TableView). Another approach here: How to populate UITableView from the bottom upwards?

                List {
                    ForEach(itemsData.messages) { item in
                        ChatRow(item: item)
                    }
                    Text("Load more messages...")
                        .onAppear() {
                            print("Load more messages...")
                            self.itemsData.next()
                    }
                }

My assumption is to get something .onAppear or override methods to make this work.

Seems like SwiftUI too young to go that deep.

Another question: do they have an API to programmatically scroll in List?

Hope I'm not duplicating any questions.

Using it for anonymous chat app https://en.lonje.com/

Roman Vasilyev
  • 149
  • 4
  • 12

2 Answers2

15

There is a trick on UITableView that you flip the table and each cell. So it appears to be filling from bottom. You can do this trick in SwiftUI too:

Fully Working Demo:

struct ContentView: View {
    @State private var ids = [String]()

    init() {
        UITableView.appearance().tableFooterView = UIView()
        UITableView.appearance().separatorStyle = .none
    }

    var body: some View {
        ZStack {
            List(ids, id: \.self) { id in
                Text(id).scaleEffect(x: 1, y: -1, anchor: .center)
            }.scaleEffect(x: 1, y: -1, anchor: .center)

            Button("Touch") {
                self.ids.append(UUID().uuidString)
            }
        }
    }
}
Mojtaba Hosseini
  • 95,414
  • 31
  • 268
  • 278
  • **Note that** I replaced all data with a mock duo lack of information about your structures. – Mojtaba Hosseini Oct 22 '19 at 21:17
  • Thank you, this is exactly what I've looked for. But in my improved example `reversed List` have strange `padding`, it looks like some List "header" or something else, can't get rid of it. Here is my snippet: https://pastebin.com/rRGtewzG – Roman Vasilyev Oct 23 '19 at 02:21
  • 1
    You should not update your question using the answer. Please revert it back to the original and ask a new question about that wired padding and link it in the comment here. So I can investigate on it ;) – Mojtaba Hosseini Oct 23 '19 at 05:04
  • Updated, thank you for quick reply. https://stackoverflow.com/questions/58516228/bottom-padding-in-reverted-list-swiftui Btw, may be you can recommend some example for programmatic scrolling in list, for instance how to `scrollToPosition(at: i)`? – Roman Vasilyev Oct 23 '19 at 05:51
  • There is no direct api yet, but I will look for a workaround – Mojtaba Hosseini Oct 23 '19 at 06:24
  • About direct API may be exists method to focus list on some item or at list set some offset? – Roman Vasilyev Oct 23 '19 at 15:40
  • What about Lists that have Edit enabled and implement the onDelete modifier? – Michael Neas Jul 15 '20 at 21:55
1

@cipais's answer worked well. https://stackoverflow.com/a/61036551/12208004

List(chatController.messages, id: \.self) { message in
    MessageView(message.text, message.isMe)
        .rotationEffect(.radians(.pi))
        .scaleEffect(x: -1, y: 1, anchor: .center)
}
.rotationEffect(.radians(.pi))
.scaleEffect(x: -1, y: 1, anchor: .center)
user12208004
  • 1,704
  • 3
  • 15
  • 37