How can I chage the text color for large titles? I want it to be white.I tried to set the titleTextAttributes like this:self.navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.navigationBar.titleTextAttributes = [
NSAttributedStringKey.foregroundColor.rawValue: UIColor.white
]But the text only turns up white when I scroll and it is displayed in the middle as usual.
Post
Replies
Boosts
Views
Activity
I have a performance issue with List when I have a large amount of data that is replaced. Given the code below, a data set of about 3500 name items are loaded from a fetch request. Depending of the selected gender in the segmented picker these items are filtered and the displayed in the List. When the List first render I have no performance issue with the loading and rendering of items. It scrolls nicely and smoothly through 1700 items. But as soon as I switch gender through the segemented picker it takes about 30-45 seconds to render the List again.I think this has to do with removing 1700 items and the inserting 1500 items again from the List. Is there a best practice how to reload a large amount of items in SwiftUI? Or can I reset the List before I load it again, since there is no issue initially.Anyone else having issue same issue?struct NameList: View {
@ObservedObject fileprivate var global = GlobalSettings()
@FetchRequest(
entity: Name.entity(),
sortDescriptors: [NSSortDescriptor(key: "name", ascending: true)]
) var names: FetchedResults<Name>
@State var selectedGender = Defaults.gender
var body: some View {
let filtered = names.filter { $0.gender == self.selectedGender }
return NavigationView {
VStack {
Picker("Gender", selection: $global.gender) {
Text(Gender.female.rawValue.uppercased())
.tag(Gender.female)
Text(Gender.male.rawValue.uppercased())
.tag(Gender.male)
Text(Gender.unisex.rawValue.uppercased())
.tag(Gender.unisex)
}
.pickerStyle(SegmentedPickerStyle())
.padding()
List( filtered, id: \.self) { (item: Name) in
NameListRow(item: item)
}
}
}
.onReceive(Defaults.publisher(for: \.gender)) { (gender) in
self.selectedGender = gender
}
}
}
Is there a way to have a list in SwiftUI that has a max width in grouped style like the Settings app on an iPad Pro 12.9" ?
I have tried with something like:
List {
	 Text("Hello, world!").padding()
}
.frame(maxWidth: 600)
.listStyle(InsetGroupedListStyle())
and it gets me half the way. The list is centered with the max width. However, I can't set the background in a way that it covers the whole page. The List view sets its background to the system grouped background as expected for InsetGroupedListStyle. And I can wrap the list in a HStack and set a background on that. But the list even add background color up in the navigation bar, but that I cannot change. So I still can't figure out a way to do it.
HStack {
	Spacer()
	List {
		Text("Hello, world!").padding()
	}
.frame(maxWidth: 600)
.listStyle(InsetGroupedListStyle())
Spacer()
}
.background(Color(UIColor.systemGroupedBackground))
I can probably accomplish what I want with just a ScrollView and make my own list. But I think that will reduce the performance?
Can anyone help me with this? I try to use the LazyVGrid and load images from CoreData stored in a binary data field. How can I make the image loading asynchronous? I have tried to look how ImageLoader's for remote images work, but I can't make it work with images loading from CoreData.
My ImageLoader works but the ScrollView freeze until all images are loaded.
protocol ImageLoaderModel {
func thumbnailData() -> Data?
func thumbnailCacheKey() -> String
}
struct ContentView: View {
@FetchRequest(
entity: Item.entity(),
sortDescriptors: [NSSortDescriptor(key: "name", ascending: true)]
) private var items: FetchedResults<Item>
var columns: [GridItem] = [
GridItem(.adaptive(minimum: 150))
]
var body: some View {
ScrollView {
LazyVGrid(columns: columns, alignment: .center, spacing: 20) {
ForEach(items, id: \.self) { item in
GridItemView(item: item)
}
}
.padding()
}
}
}
struct GridItemView: View {
@ObservedObject var item: Item
var body: some View {
VStack(alignment: .center) {
if item.thumbnail != nil {
AsyncImage(model: item)
} else {
RoundedRectangle(cornerRadius: 5)
.frame(width: 150, height: 112)
}
Text(item.name ?? "")
.font(.subheadline)
}
}
}
struct AsyncImage: View {
@ObservedObject private var loader: ImageLoader
init(model: ImageLoaderModel) {
loader = ImageLoader(model: model)
}
var body: some View {
image.onAppear(perform: loader.load)
}
private var image: some View {
Group {
if loader.uiImage != nil {
Image(uiImage: loader.uiImage!)
.resizable()
.scaledToFill()
.frame(width: 150, height: 112)
.cornerRadius(5)
.clipped()
} else {
ProgressView()
.frame(width: 150, height: 112)
}
}
}
}
class ImageLoader: ObservableObject {
@Published var uiImage: UIImage?
private var model: ImageLoaderModel
private var cache = ImageCache.shared
init(model: ImageLoaderModel) {
self.model = model
}
func load() {
let cacheKey = self.model.thumbnailCacheKey()
if let uiImage = cache[cacheKey] {
self.uiImage = uiImage
return
}
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
guard let data = self?.model.thumbnailData() else { return }
if let uiImage = UIImage(data: data) {
DispatchQueue.main.async {
self?.cache[cacheKey] = uiImage
self?.uiImage = uiImage
return
}
}
}
}
}
When I using a ScrollView the title isn't smoothly animated up to the inline version when I scroll. Just by changing the ScrollView to a List makes it scroll as it should. Is this a known issue ?
struct ContentView: View {
var body: some View {
NavigationView {
ScrollView {
Text("Hello, world!").padding()
}
.navigationTitle("Title")
}
}
}
Ever since I updated to iOS 14 beta 5 I have issues with my apps on the device as well as simulator. The app wont start and it just show a blank screen. The cpu, disc and network activity just show zero.
Even if you create a new project and just build from the example it wont work. Anyone else experiencing this?
The apps are build with SwiftUI.
I having issues trying to understand combine and publishers. I have a PhotoPicker that selects one ore more images from the photo library. These images should be added to my core data model. This is handled in my model class.
However, I ends up in an infinit loop that I don't understand. The View keeps updating and the onReceive method keeps executing over and over again making the View render again. Below is a sample code (without core data) that behaves the same
Sample code:
struct MyImage: Hashable {
var id: String
var uiImage: UIImage
}
class Model: ObservableObject {
@Published var images: [MyImage] = []
func add(uiImage: UIImage) {
let id = UUID().uuidString
let image = MyImage(id: id, uiImage: uiImage)
self.images.append(image)
}
}
struct ContentView: View {
@StateObject var model = Model()
@State var showPhotoPicker = false
@State var pickerResult: [UIImage] = []
var body: some View {
VStack {
ForEach(model.images, id: \.self) { image in
Text(image.id)
				// TODO: Add actual image
}
Button(action: { showPhotoPicker.toggle() }) {
Text("ADD PHOTO")
}
.fullScreenCover(isPresented: $showPhotoPicker) {
let config = PHPickerConfiguration(photoLibrary: PHPhotoLibrary.shared())
PhotoPicker(configuration: config, pickerResult: $pickerResult)
}
}
.onReceive(pickerResult.publisher, perform: { image in
model.add(uiImage: image)
})
}
}
Can someone explain what is happening?