Hi guys,
I am developing an app which is a messaging app and it needs to work smoothly.
However, I ran into an issue where I couldn't scroll over RTL text properly. It doesn't matter whether I am using UIKit or SwiftUI it just stutters.
I tested out on an iPad with a promotion display / iPhone XS and 15 pro-Max and the result was the same.
Someone said using an RTL font could resolve the issue however it did not.
And if you uncomment the line 48 and comment the line 49 you will see the app run smoothly without a hitch.
It is overtly clear in messaging apps that the app stutters, and our users have complained about it a lot.
struct UItableViewTest: View {
var body: some View {
SwiftUI.NavigationStack {
NavigationLink {
RandomItemsTableViewControllerWrapper()
} label: {
Text("move to table view controller")
}
}
}
}
struct RandomItemsTableViewControllerWrapper: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UIViewController {
return RandomItemsTableViewController()
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
}
class RandomItemsTableViewController: UITableViewController {
private let cellReuseIdentifier = "Cell"
private var items: [String] = []
private let font = UIFont(name: "RTLFONT", size: 16)
override func viewDidLoad() {
super.viewDidLoad()
generateRandomItems()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)
}
private func generateRandomItems() {
let maxRTLLength = MockTexts.rtlText.count
let numberOfItems = 100
for _ in 0..<numberOfItems {
let randomLength = Int.random(in: 10...maxRTLLength)
let randomRTL = Bool.random()
// let randomText = String(MockTexts.loremIpsum.prefix(randomLength))
let randomText = String(randomRTL ? MockTexts.rtlText.prefix(randomLength) : MockTexts.loremIpsum.prefix(randomLength))
items.append(randomText)
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath)
cell.textLabel?.text = items[indexPath.row]
cell.textLabel?.numberOfLines = 0
cell.textLabel?.font = font
return cell
}
}
#Preview {
UItableViewTest()
}
struct MockTexts {
static let loremIpsum = """
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed commodo gravida sagittis.\n Nulla facilisi. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; \n Nam eleifend metus leo, id maximus ante posuere ac.\n Fusce ultrices fringilla malesuada.\n Sed eget lectus ut nisl condimentum scelerisque.\n Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed commodo gravida sagittis.\n Nulla facilisi. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; \n Nam eleifend metus leo, id maximus ante posuere ac.\n Fusce ultrices fringilla malesuada.\n Sed eget lectus ut nisl condimentum scelerisque.\n Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed commodo gravida sagittis.\n Nulla facilisi. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; \n Nuada.\n Sed eget lectus ut nisl condimentum scelerisque.\n Pellentesque habit
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed commodo gravida sagittis.\n Nulla facilisi. Vesti
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed commodo gravida sagittis.\n Nulla facilisi. Vestiabitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed commodo gravida sagittis.\n Nulla facilisi. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; \n Nam eleifend metus leo, id maximus ante posuere ac.\n Fusce ultrices fringilla malesuad\n
te ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; \n Nam eleifend metus leo, id maximus ante posuere ac.\n Fusce ultrices fringilla malesuada.\n Sed eget lectus ut nisl condimentum scelerisque.\n Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
"""
static let rtlText = """
سلام این یه متن طولانی است که من برای تست دارم می نویسم ببینم چه جوری کار میکنه متن های خیلی طولانی فارسی.
سلام این یه متن طولانی است که من برای تست دارم می نویسم ببینم چه جوری کار میکنه متن های خیلی طولانی فارسی.
سلام این یه متن طولانی است که من برای تست دارم می نویسم ببینم چه جوری کار میکنه متن های خیلی طولانی فارسی.
سلام این یه متن طولانی است که من برای تست دارم می نویسم ببینم چه جوری کار میکنه متن های خیلی طولانی فارسی.
سلام این یه متن طولانی است که من برای تست دارم می نویسم ببینم چه جوری کار میکنه متن های خیلی طولانی فارسی.
سلام این یه متن طولانی است که من برای تست دارم می نویسم ببینم چه جوری کار میکنه متن های خیلی طولانی فارسی.
سلام این یه متن طولانی است که من برای تست دارم می نویسم ببینم چه جوری کار میکنه متن های خیلی طولانی فارسی.
سلام این یه متن طولانی است که من برای تست دارم می نویسم ببینم چه جوری کار میکنه متن های خیلی طولانی فارسی.
سلام این یه متن طولانی است که من برای تست دارم می نویسم ببینم چه جوری کار میکنه متن های خیلی طولانی فارسی.
سلام این یه متن طولانی است که من برای تست دارم می نویسم ببینم چه جوری کار میکنه متن های خیلی طولانی فارسی.
سلام این یه متن طولانی است که من برای تست دارم می نویسم ببینم چه جوری کار میکنه متن های خیلی طولانی فارسی.
سلام این یه متن طولانی است که من برای تست دارم می نویسم ببینم چه جوری کار میکنه متن های خیلی طولانی فارسی.
سلام این یه متن طولانی است که من برای تست دارم می نویسم ببینم چه جوری کار میکنه متن های خیلی طولانی فارسی.
سلام این یه متن طولانی است که من برای تست دارم می نویسم ببینم چه جوری کار میکنه متن های خیلی طولانی فارسی.
سلام این یه متن طولانی است که من برای تست دارم می نویسم ببینم چه جوری کار میکنه متن های خیلی طولانی فارسی.
سلام این یه متن طولانی است که من برای تست دارم می نویسم ببینم چه جوری کار میکنه متن های خیلی طولانی فارسی.
سلام این یه متن طولانی است که من برای تست دارم می نویسم ببینم چه جوری کار میکنه متن های خیلی طولانی فارسی.
سلام این یه متن طولانی است که من برای تست دارم می نویسم ببینم چه جوری کار میکنه متن های خیلی طولانی فارسی.
سلام این یه متن طولانی است که من برای تست دارم می نویسم ببینم چه جوری کار میکنه متن های خیلی طولانی فارسی.
سلام این یه متن طولانی است که من برای تست دارم می نویسم ببینم چه جوری کار میکنه متن های خیلی طولانی فارسی.
"""
}
Post
Replies
Boosts
Views
Activity
Hi, I have found another bug if I'm not mistaken in core data.
When we are using a derived attribute in our xcdatamodel file after making the mapping file there is an error:
Can't find mapping model for migration
If you are looking to reproduce the bug I made a super simple example app at my branch in the link below:
https://github.com/hamed8080/LeitnerBox/tree/fix_migration
Keep that in mind if I remove the derived attribute and afterward make a migration with a new mapping file, it works correctly!
Hi,
As you can see in the code below whenever I open the app in the normal mode app works fine and the detail view shows data properly. However, in split screen the app lost data of the selected item. I'm sure there is a bug in here unless I should manage it by myself which unacceptable!
@main
struct TestSwiftUIApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct Employee: Identifiable {
let name: String
let id: Int
}
struct ContentView: View {
@State
var selectedEmployeeId: Employee.ID?
let employess: [Employee] = [.init(name: "Hamed", id: 1), .init(name: "John", id: 2)]
var body: some View {
NavigationSplitView {
List(employess, selection: $selectedEmployeeId) { employee in
Text(employee.name)
}
} detail: {
NavigationStack {
if let employee = employess.first{$0.id == selectedEmployeeId} {
EmployeeDetails(employee: employee)
}
}
}
}
}
struct EmployeeDetails: View {
let employee: Employee
var body: some View {
Text("Detail of empolyee\(employee.name) with id: \(employee.id)")
}
}
I have a problem with SwiftUI and tabview and the problem is when I'm on a second navigation page it's back to the first navigation when I need to open a sheet. Tab1->FirstView->Secondview->Sheet after the sheet opened the navigation view behind the scene switched to first navigation!
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView{
TabView{
Tab1()
.tabItem({Text("tab1")})
Tab2()
.tabItem({Text("tab2")})
}
}
}
}
struct Tab1: View {
@State
var shownextPage = false
var body: some View {
ZStack{
Button ("Next Page"){
shownextPage = true
}
NavigationLink( destination: SecondView(), isActive: $shownextPage) {
EmptyView()
}
}
}
}
struct Tab2: View {
var body: some View {
Text("Tab 2 detail")
}
}
struct SecondView: View {
@State
var showSheet:Bool = false
var body: some View {
VStack{
Button {
showSheet = true
} label: {
Text("open Sheet")
.padding()
}
.sheet(isPresented: $showSheet, onDismiss: nil) {
Text("hello in sheet")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
I run this code on simulator and device with iOS 15 but when I scroll the List items overlap navigation bar title. but I found that if I add a padding-top with 1 on the List then the view works correctly!
struct ContentView: View {
var body: some View {
NavigationView{
VStack{
List {
ForEach(1...100 , id:\.self) { index in
Text("Message \(index)")
.listRowBackground(Color.clear)
}
}
.background(
ZStack{
Image("chat_bg")
.resizable()
.opacity(0.25)
LinearGradient(gradient: Gradient(colors: [Color.black.opacity(0.9),
Color.blue.opacity(0.6)]),
startPoint: .top,
endPoint: .bottom)
}
)
.listStyle(PlainListStyle())
SendContainer(message: "")
}
.layoutPriority(1)
.navigationBarTitle(Text("Chats"), displayMode: .inline)
}
}
}
struct SendContainer:View{
@State
var message: String
var body: some View{
HStack{
Image(systemName: "paperclip")
.font(.system(size: 24))
.foregroundColor(Color.gray)
TextField("Type Text Here .... ",text:$message)
.cornerRadius(16)
Image(systemName: "mic")
.font(.system(size: 24))
.foregroundColor(Color.gray)
Image(systemName: "arrow.up.circle.fill")
.font(.system(size: 24))
.foregroundColor(Color.blue)
}
.frame(height: 48)
.padding(8)
.background(Color.white.ignoresSafeArea())
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
I created a list to expand and collapse when the user taped on a row but as you can see the animation in collapse mode is not working properly. and the whole row getting closed before animation executed only on iOS 15 but on ios 14 it was working ok.
struct MyRow:View{
@State var isExpanded = false
var body: some View{
VStack{
VStack{
HStack{
Image("avatar")
.resizable()
.frame(width: 64, height: 64)
Text("Test Row with Long Title and really long Title ")
Spacer()
}
if isExpanded{
Button("Click on me"){
}
.foregroundColor(Color.blue)
}
}
.padding(16)
.background(Color.primary.opacity(0.08))
.cornerRadius(16)
}
.onTapGesture {
withAnimation {
isExpanded.toggle()
}
}
}
}
struct MyList_Previews: PreviewProvider {
static var previews: some View {
MyList()
.previewDevice("iPhone 12 Pro Max")
.environmentObject(AppState.shared)
}
}
struct MyList :View{
var body: some View{
List{
ForEach(1...5 , id:\.self){ content in
MyRow()
}
}
.animation(.default)
.listStyle(PlainListStyle())
}
}