I am using TextEditor with the String type right now but I want to use AttributedString because I want to find every character that starts with a # symbol and mark it a different color using range.
How can I use AttributedString with TextEditor?
struct PlaygroundView: View {
#State private var text = AttributedString("")
var body: some View {
TextEditor(text: text)
}
}
returns to me Cannot convert value of type 'AttributedString' to expected argument type 'Binding<String>'
Related
I am trying to get the view inside the body for observing purpose, but looking for different ways the view inside the body can be accessed.
struct ContentView: View {
#State var userNameText: String
var body: some View {
startObservingInput()
return TextField("hello", text: $userNameText)
}
func startObservingInput() {
// How do we get TextField instance here.
// Option 1 - Pass as parmeter here.
// Option 2 - Is there a way to get view from body ex: self.body.textFieldView
// Option 3 - can create as a property in CotentView but the text binding refers to self which will not be allowed before its initalized so that will fail to compile
//var textField = TextField("hello", text: $userNameText)
}
}
Option 1 is simple, where we pass the TextField view.
Option 2 is something I am looking for, if we can get any view inside the hierarchy. In this case Text Field.
Option 3, Tried to create a property but I get the following error.
ex:
struct ContentView: View {
#State var userNameText: String
var textField = TextField("hello", text: $userNameText)
......
}
Cannot use instance member '$userNameText' within property initializer; property initializers run before 'self' is available
SwiftUI is different from what you're probably used to. Unlike UIKit, you don't "store" views in properties. There's no delegates either.
Instead, you directly pass in a property — userNameText — that will be linked to the text field's text. Since this updates itself automatically, you can use the onChange modifier to observe changes.
struct ContentView: View {
#State var userNameText: String
var body: some View {
TextField("hello", text: $userNameText)
.onChange(of: userNameText) { newValue in
print("Text changed to: \(newValue)")
}
}
}
Here is what I did, look at it:
//
// ViewProp.swift
// SwiftDemo1
//
// Created by CreoleMacbookPro on 12/19/22.
//
import SwiftUI
struct ViewProp: View {
#State var userNameText: String = " "
var body: some View {
let textField: TextField<Text> = TextField("hello", text: $userNameText)
let simpleText: Text = Text("Hello, World!")
let _ = print(type(of: textField))
startObservingInput(textField: textField)
Button {
userNameText = "Jatin Bhuva"
} label: {
Text("Press Me..")
}
// textField
}
func startObservingInput(textField: TextField<Text>) -> some View {
textField
// How do we get TextField instance here.
// Option 1 - Pass as parmeter here.
// Option 2 - Is there a way to get view from body ex: self.body.textFieldView
// Option 3 - can create as a property in CotentView but the text binding refers to self which will not be allowed before its initalized so that will fail to compile
//var textField = TextField("hello", text: $userNameText)
}
}
struct ViewProp_Previews: PreviewProvider {
static var previews: some View {
ViewProp()
}
}
My #Binding weight variable connects to my Source of Truth further up in my code. But I also need to let my user edit this with a TextField(). So, I am trying to create a local variable of type String because TextField requires type Bindable.
Perhaps I'm approaching this wrong.
struct SetsBar: View {
#Binding var weight: Int
#Binding var reps: Int
#State var weightString: String = String(weight)
init(weight: Binding<Int>, reps: Binding<Int>) {
self._weight = weight
self._reps = reps
}
var body: some View {
HStack {
TextField("\(weight)", text: $weightString)
}
}
}
I get an error on my #State property
Cannot use instance member 'weight' within property initializer; property initializers run before 'self' is available
You can bind weight directly using TextField variant with formatter (configuring formatter as much as needed, below is simplified variant for demo), like
var body: some View {
HStack {
TextField("\(weight)", value: $weight, formatter: NumberFormatter())
}
}
I am writing an App to store Points of Interest in icloud. The visualisation is either a map with annotations or a list.
To select the Type of the Poi I use a Picker based on an enum:
import SwiftUI
enum Poitypes: String, Hashable, CaseIterable {
case dogStation = "Dog Station"
case trash = "Mülleimer"
case poop = "Hundehaufen"
case bag = "Hundebeutel"
}
struct PoiTypeView: View {
#State private var selection = Poitypes.dogStation
#State private var showsPicker: Bool = false
#Binding var selectedPoi: Poi
var body: some View {
VStack {
Text("Welcher Type befindet sich hier?")
.padding(20)
Picker(selection: $selection, label: Text("POI Type")) {
ForEach(Poitypes.allCases, id:\.self) { value in
Text(value.rawValue)
.tag(value)
}
}
.pickerStyle(InlinePickerStyle())
}
}
}
The attribute I store the POItype is of type string:
[Screenshot of entity][1]
[1]: https://i.stack.imgur.com/Mgcfa.png
Selecting a value I store the tag - so far so good.
When I want to update a POI from the list or map view, how can I achieve that the picker is showing the stored selection?
I store the selected POI in an object of Type POI and pass it to the picker view.
But then I do not know how to "convert" the string to be of type Poitypes so that the selection will be updated.
when i pass an interpolated string with Image into a Text view, it returns incorrectly.
import SwiftUI
struct UserMediaCell: View {
var body: some View {
subView(label:"\(Image(systemName: "ellipsis"))")
// shows incorrectly:
// Image(provider: SwiftUI.ImageProviderBox<SwiftUI.Image.(unknown context at $18c350410).NamedImageProvider>)
Text("\(Image(systemName: "ellipsis"))")
// shows correctly. (sf symbol visible)
}
}
struct subView: View {
#State var label: String
var body: some View {
Text(label)
}
}
how do i solve this?
This is because your subview is taking the result of the string interpolation as a String type. Where the Text view that is working correctly is not using a String to initialize the view, but a Localized String Key.
Change your subview to account for that like so:
// Structs, Classes, and Actors should start with a Capital Letter BTW
struct SubView: View {
#State var label: LocalizedStringKey
var body: some View {
Text(label)
}
}
I am having real difficulty using Fetch Data from Core Data Entity.
All I need to do is to Fetch Data and use within my Code.
My approach technique maybe wrong hence the difficulty.
I hoped to get the Data and store into an array
I have a function which processed the data, but all I am able to do is to display the result in a view.
I would like to store the data in an Array, where I attempted to EmptyArray.append[newElement]
Error: Code is dictionaryWord.append(word.englishName) and error is Type of expression is ambiguous without more context
//Game Play
struct gamePlay: View {
//Set CoreData environment
#Environment(\.managedObjectContext) var managedObjectContext
#FetchRequest(entity: Dictionary.entity(), sortDescriptors: []) var dictionary: FetchedResults<Dictionary>
//Variables for Game Play
#State private var dictionaryWord: [String] = []
#State private var correctAnswer = Int.random(in: 0...2)
//Function to retrieve records from CoreData
func processListPicture() -> some View {
NavigationView {
VStack {
List(dictionary,id: \.self) { word in
HStack {
Text(word.englishName)
Image(word.imageName)
.resizable()
.frame(width: 50, height: 50)
.scaledToFit()
Text("- Urhobo: \(word.urhoboName)")
}
}//End of ForEach / List
}
}.navigationBarTitle(Text("English Word Translator"),displayMode: .inline)
}//End of Function
If I understand your question, you are trying to convert FetchedResults<Result> (called 'dictionary') to an array, where Result is a CoreData's entity called Dictionary.
To shuffle it, you can do:
let shuffledDictionaries: [Dictionary] = dictionary.shuffled()
If you wan conserve the original order:
let dictionaries: [Dictionary] = dictionary.map { $0 }
Or if you want any specific order:
let sortedDictionaries: [Dictionary] = dictionary.sorted(by: { ... })