74235


Qiita
APIを使って記事一覧（タイトル、日時、タグ）を表示するアプリを作成しているのですが、スクロールするとタグの表示がズレるという現象に悩んでいます。  
おそらく、Listにてタグをforeachの繰り返しで表示していることが原因なのかなと考えています。（繰り返しが終了する前にスクロールされてる？）  
どなたかこちらの解決策をご教授いただければ助かります。

[code]

    import SwiftUI
    
    struct ContentView: View {
        
        @ObservedObject var networkManager = NetworkManager()
        
        var body: some View {
            NavigationView {
                VStack {
                    List(networkManager.posts) { post in
                        NavigationLink(destination: DetailView(url: post.url)) {
                            VStack {
                                Text(post.title)
                                    .font(.callout)
                                    .fontWeight(.medium)
                                    .frame(maxWidth: .infinity, alignment: .leading)
                                HStack {
                                    Image(systemName:"tag")
                                        .resizable()
                                        .frame(width: 13.0, height: 13.0, alignment: .leading)
                                    
                                    // 以下タグ表示の処理
                                    ForEach(0..<post.tags.count) { i in
                                        if let tag = post.tags[i].name {
                                            Text(tag)
                                                .font(.caption)
                                        }
                                    }
                                }
                                .frame(maxWidth: .infinity, alignment: .leading)
                                
                                HStack {
                                    Text("更新日：")
                                    Text(post.updated_at.prefix(10))
                                }
                                .font(.caption)
                                .frame(maxWidth: .infinity, alignment: .leading)
                                
                            }
                        }
                    }
                }
                .navigationBarTitle(Text("MyQiita"))
            }
            .onAppear(perform: {
                self.networkManager.fetchData(searchWord: "")
            })
        }
        
        //MARK: - navigationBarの色設定
        init() {
            setupNavigationBar()
        }
        
        func setupNavigationBar() {
            let appearance = UINavigationBarAppearance()
            appearance.configureWithOpaqueBackground()
            appearance.backgroundColor = .systemGreen
            appearance.titleTextAttributes = [.foregroundColor: UIColor.white]
            appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
            UINavigationBar.appearance().standardAppearance = appearance
            UINavigationBar.appearance().scrollEdgeAppearance = appearance
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
    
[/code]

NetworkManager.swift

[code]

    import Foundation
    
    class NetworkManager: ObservableObject {
        
        @Published var posts = [Results]()
        
        func fetchData(searchWord: String) {
            let urlString = "https://qiita.com/api/v2/items?page=1&per_page=20&query=tag%3A" + searchWord
            if let url = URL(string: urlString) {
                let session = URLSession(configuration: .default)
                let task = session.dataTask(with: url) { (data, response, error) in
                    if error == nil {
                        let decoder = JSONDecoder()
                        if let safeData = data {
                            do {
                                let results = try decoder.decode([Results].self, from: safeData) // 戻り値の型は第一引数によって決まる
                                DispatchQueue.main.async {
                                    self.posts = results
                                }
                            } catch {
                                print("Error(data):\(error)")
                            }
                        }
                    }
                }
                task.resume()
            }
            
        }
        
    }
    
[/code]

PostData.swift

[code]

    import Foundation
    
    struct Results: Decodable, Identifiable {
        let id: String
        let title: String
        let updated_at: String
        let url: String
        let tags: [Tags]
    }
    
    struct Tags: Decodable {
        let name: String
    }
    
[/code]

![画像の説明をここに入力](https://i.stack.imgur.com/S2Sns.jpg)


CC BY-SA 4.0
2021-02-20T13:13:24.543
74160
2021-02-23T14:37:41.897
2021-02-21T06:13:13.353
3060
44044
question
swiftui
SwiftUIのList内の表示が、スクロールによってずれてしまう


>
> 手元で全く同じ事象が再現できない(別の事象が発生してクラッシュする)ので、確実なことが言える状態ではないんですが、ForEach(0..<post.tags.count)の代わりにForEach(post.tags.indices,
> id: .self)として見るとどうなりますか?

指摘いただいた部分を以下のように修正することで解決できました。

[code]

    ForEach(post.tags.indices, id: \.self) { i in
     if let tag = post.tags[i].name {
      Text(tag)
       .font(.caption)
     }
    }
    
[/code]

List内でForEach処理をする場合はarrayでもインデックスを利用した方が良いみたいです。


CC BY-SA 4.0
2021-02-23T14:37:41.897
74235
2021-02-23T14:37:41.897
44044
74160
answer