Проблемы с версткой в ​​SwiftUI на TVOS - PullRequest
0 голосов
/ 11 июля 2020

У меня есть работоспособный пользовательский интерфейс в TVOS с использованием SwiftUI, но я не могу понять, как сделать его правильным.

Цели:

  1. Экран полноэкранный, не вставлено в безопасную область
  2. Изображение альбома квадратное, соотношение сторон сохранено, заливка сверху вниз
  3. Текст альбома и исполнителя удобно размещается рядом с обложкой альбома
import SwiftUI

struct ContentView: View {
    @ObservedObject var ds = DataStore()
    
    var body: some View {
        HStack(alignment: .top) {
            if (ds.currentRoom.albumImage != nil) {
                Image(uiImage: ds.currentRoom.albumImage!)
                    .resizable()
                    .aspectRatio(contentMode: ContentMode.fit)
                    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
                    .background(Color.black)
                
            }
            VStack(alignment: .leading, spacing: 8) {
                Text(ds.currentRoom.artist ?? "?")
                    .font(.system(.title, design: .default))
                    .bold()
                    .foregroundColor(Color.gray)
                    .padding(.top, 100)
                Text(ds.currentRoom.title ?? "?")
                    .font(.system(.headline, design: .default))
                    .foregroundColor(Color.gray)
                    .padding(.bottom, 100)
                Button(action: { print ("pressed!" )} ) {
                    Image(systemName: "playpause")
                        .font(.system(.title, design: .default))
                        .foregroundColor(Color.gray)
                        .padding(30)
                        .overlay(
                            RoundedRectangle(cornerRadius: 16)
                                .stroke(Color.green, lineWidth: 4)
                    )
                }
            }
        }
        .padding(20)
        .background(Color.black)
        .edgesIgnoringSafeArea(.all)
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

На случай, если это поможет, вот соответствующие методы помощника и DataSource:

Класс DataStore () имеет этот метод:

import SwiftUI
import Combine

class CurrentRoom {
    var artist: String?
    var title: String?
    var album: String?
    var albumArtURI: String?
    var absoluteAlbumArtURI: String?
    var albumImage: UIImage?
}

class DataStore: ObservableObject {
    @Published var currentRoom: CurrentRoom = CurrentRoom()
        
    init() {
        getCurrentRoom()
    }
    
    func getCurrentRoom() {
        currentRoom.artist = "Eilen Jewell"
        currentRoom.album = "Sundown over Ghost Town"
        currentRoom.title = "Half-Broke Horse"
        currentRoom.absoluteAlbumArtURI = "https://images-na.ssl-images-amazon.com/images/I/71mkKfTQD0L._SX425_.jpg"
        currentRoom.albumImage = Api().getImageDataFromURI(UrlAsString: currentRoom.absoluteAlbumArtURI)
    }
}

struct DataStore_Previews: PreviewProvider {
    static var previews: some View {
        /*@START_MENU_TOKEN@*/Text("Hello, World!")/*@END_MENU_TOKEN@*/
    }
}

Наконец:

class Api {
    func getImageDataFromURI(UrlAsString: String?) -> UIImage? {
        if let URI = UrlAsString {
            if URI.starts(with: "http") {
                if let url = URL(string: URI) {
                    let data = try? Data(contentsOf: url)

                    if let imageData = data {
                        return UIImage(data: imageData)
                    }
                }
            }
        }
        return nil
    }
}

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

1 Ответ

1 голос
/ 28 июля 2020

Вы можете либо go с ответом Asperis, либо, если ContentMode.Fit важен для вас (поскольку вы не хотите обрезать изображение), просто удалите часть ширины модификатора кадра на своем изображении и затем добавьте разделитель позади VStack, который поглотит все остальное:

struct ContentView: View {
@ObservedObject var ds = DataStore()

var body: some View {
    HStack(alignment: .top) {
            if (ds.currentRoom.albumImage != nil) {
                Image(uiImage: ds.currentRoom.albumImage!)
                    .resizable()
                    .aspectRatio(contentMode: ContentMode.fit)
                    .frame(minHeight: 0, maxHeight: .infinity)
                    .background(Color.black)
                
            }
            VStack(alignment: .leading, spacing: 8) {
                Text(ds.currentRoom.artist ?? "?")
                    .font(.system(.title, design: .default))
                    .bold()
                    .foregroundColor(Color.gray)
                    .padding(.top, 100)
                Text(ds.currentRoom.title ?? "?")
                    .font(.system(.headline, design: .default))
                    .foregroundColor(Color.gray)
                    .padding(.bottom, 100)
                Button(action: { print ("pressed!" )} ) {
                    Image(systemName: "playpause")
                        .font(.system(.title, design: .default))
                        .foregroundColor(Color.gray)
                        .padding(30)
                        .overlay(
                            RoundedRectangle(cornerRadius: 16)
                                .stroke(Color.green, lineWidth: 4)
                    )
                }
            }
            .padding(.leading, 10)
        Spacer()
        }
    .padding(20)
    .background(Color.black)
    .edgesIgnoringSafeArea(.all)
    }
}

Это приведет к следующему изображению: Правильный макет

...