Не удается отобразить всю строку в списке с помощью SwiftUI

#ios #swift #swiftui #swiftui-list

Вопрос:

Когда вы открываете образец проекта:

Сначала нажмите один раз на строку, и появится кнопка «Плюс». После того, как вы один раз нажмете кнопку «Плюс», к строке будет добавлен символ «плюс». Если я нажму на кнопку много раз, появится строка ... (показано на рисунке ниже). Я этого не ожидал, я ожидаю, что высота строки будет автоматически увеличена, чтобы можно было отобразить всю строку. Что я должен сделать, чтобы это исправить?

введите описание изображения здесь

Если я нажму кнопку «Плюс» 5-6 раз, высота строки автоматически увеличится, как и ожидалось.

введите описание изображения здесь

Основной код проекта в примере проекта:

Просмотр содержимого.swift

 struct ContentView: View {
    
    @EnvironmentObject var userData: UserData
    
    var body: some View {

        HStack {
            List {
                ForEach(userData.subtasks) { subtask in
                    SubtaskRowNextToCard(subtaskModel: subtask)
                }
            }
            
            if userData.currentSubtask != nil {
                SubtaskCard()
                    .padding(.all)
            }
        }
        .onAppear {
                        
            for _ in 0..<20 {
                appendASubtask()
            }
            
        }
        
    }
    
    func appendASubtask() {
        let aSubtask = SubtaskModel(
        score: ""
        )
        
        userData.subtasks.append(aSubtask)
    }
    
}
 

Модель подзадачи.swift

 import Foundation
import SwiftUI

class SubtaskModel: ObservableObject, Identifiable {
    @Published var score: String = ""
    
    init(
        score: String
    ) {
        self.score = score
    }
}

 

SubtaskRowNextToCard.swift

 struct SubtaskRowNextToCard: View {
    
    @ObservedObject var subtaskModel: SubtaskModel
    @EnvironmentObject var userData: UserData
    
    @State var scoreWithRound: String = ""
    
    var body: some View {
        
        Button(action: {
            userData.currentSubtask = subtaskModel
        }) {
            Text(scoreWithRound)
        }
        .onAppear {
            updateScore()
        }
        .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name.init("changedCurrentSubtask"))) { obj in
            updateScore()
        }
        
    }
    
    func updateScore() {
        scoreWithRound = subtaskModel.score
    }
    
}
 

Карточка подзадачи.swift

 struct SubtaskCard: View {
    
    @EnvironmentObject var userData: UserData
        
    var body: some View {
        
        Button(action: {
            print("  button was tapped")
            appendScore(newScore: " ")
        }) {
            Image(systemName: "plus.circle.fill")
        }
        .buttonStyle(PlainButtonStyle())
        
    }
    
    func appendScore(newScore: String) {
        if let subtaskModel = userData.currentSubtask {
            subtaskModel.score = subtaskModel.score   newScore   " "
                        
            NotificationCenter.default.post(name: NSNotification.Name.init("changedCurrentSubtask"), object: nil, userInfo: nil)
        }
    }
}
 

Ответ №1:

Добавьте .fixedSize(horizontal: false, vertical: true) , и текст больше не будет обрезаться:

   ForEach(userData.subtasks) { subtask in
                    SubtaskRowNextToCard(subtaskModel: subtask).fixedSize(horizontal: false, vertical: true)
                }
 

Редактировать:
Для динамической фиксации высоты:

Замените Text на TextEditor , и вы не заметите мерцания:

 Text(scoreWithRound)
 

Для

 TextEditor(text: $scoreWithRound).allowsHitTesting(false)
 

Комментарии:

1. Это работает, но это не решило проблему идеально. Высота строки будет неожиданной (меньше обычной высоты) См. Этот пример . После нажатия кнопки плюс в течение нескольких секунд высота снова становится нормальной

2. Обновил ответ, проверьте, работает ли он для вас сейчас.