I want to hidden scroll indicator in textEditor.
Support from swiftui modifier, uikit possible ways in?
TextEditor(text: $context)
.foregroundColor(self.context == contextPlaceholder ? Color.grayA7 : Color.gray23)
.font(.bodyRegular)
.focused($isTextFieldsFocused)
.background(Color.grayF5)
.lineSpacing()
.padding(.vertical, 23)
.padding(.horizontal, 20)
.textSelection(.disabled)
.onTapGesture {
if self.context == contextPlaceholder{
self.context = ""
}
}
Using Introspect:
TextEditor(text: $context)
.introspectTextView { textView in
textView.showsVerticalScrollIndicator = false
}
if need textEditor hide scrollIndicators in iOS 16 Swift write this code:
TextEditor(text: $text)
.scrollIndicators(.hidden)
Related
Newbie at SwiftUI here. I am trying to show a dialog built in SwiftUI on top of an existing UIKit View. The idea is to be able to see the content of the UIKit view behind the SwiftUI dialog (like the default behaviour of an alert dialog box). But no what I try, I am unable to see the contents of the UIKit view. Is this even achievable?
I want an alert style dialog with background opacity adjusted somehow to see the contents of the UIKit view. Here is my output:
alert content hides the view behind it
Can somebody please point me in the right direction.
Here is my code sample:
The dialog in SwiftUI:
struct TestDialog: View {
var body: some View {
ZStack {
Rectangle().foregroundColor(Color.black.opacity(0.5))
.frame(maxHeight: .infinity)
VStack(alignment: .center, spacing: 15) {
Text(.init("Some Text"))
.multilineTextAlignment(.center)
.padding()
Button(action: {}) {
Text("Button 1")
.padding(10)
}
Button(action: {}) {
Text("Button 2")
.padding(10)
}
}
.padding()
.background(
RoundedRectangle(cornerRadius: 12)
.foregroundColor(.white))
.padding(40)
}
}
}
and the method called in my viewDidLoad():
func showTestDialog() {
let testView = TestDialog()
let testchildView = UIHostingController(rootView: testView)
addChild(testchildView)
let titleBarOffset: CGFloat = 11
testchildView.view.frame = view.frame.offsetBy(dx: 0, dy: -titleBarOffset)
view.addSubview(testchildView.view)
testchildView.didMove(toParent: self)
}
In order to see through the SwiftUI, you need to make sure it's host view has a transparent background:
testchildView.view.backgroundColor = .clear
This must be done at the host view level, since it is the parent/container.
i want to put some fixed text inside TextField like "email: ....."
I tryed this:
HStack {
Image(systemName: "list.bullet").foregroundColor(.gray)
Text("email:")
TextField("", text: Binding(
get: { viewModel.email },
set: { viewModel.email = $0 }
))
.textFieldStyle(DefaultTextFieldStyle())
.frame(width: 60)
}
.padding()
.overlay(RoundedRectangle(cornerRadius: 10).stroke(
viewModel.emailValid() ? Color.gray : Color.red, lineWidth: 1
))
The problem is that this implementation only allows to click in specific part (inside the textField space) but i want to make all clickable to be more friendly to edit.
I tryed putting TextField and Text inside ZStack but the text entered by the user in inside te "Email text".
Maybe its possible to move the textField cursor to the end of the "email" text, or another implementation?
Thanks!
So if its mainly about activating the TextField on tap/click on any area of the element, you can use programmatic focus for TextField:
struct ContentView: View {
#State var input = ""
#FocusState var focused: Bool
var body: some View {
HStack {
Image(systemName: "list.bullet").foregroundColor(.gray)
Text("email:")
TextField("", text: $input)
.frame(width: 80)
.focused($focused)
}
.padding()
.overlay(RoundedRectangle(cornerRadius: 10).stroke(
true ? Color.gray : Color.red, lineWidth: 1
))
.contentShape(Rectangle()) // makes the whole element tappable
.onTapGesture {
focused = true // sets focus for textField
}
}
}
I have added the .id(1) to the positions in the scrollview and can get it to work as expected if i add a button inside the scrollview but i want to use a picker to jump to the .id and outside the scrollview.
Im new to this.
I have this code:
if i use this button it works as expected although its placed inside the scrollview...
Button("Jump to position") {
value.scrollTo(1)
}
This is my picker...
// Main Picker
Picker("MainTab", selection: $mainTab) {
Text("iP1").tag(1)
Text("iP2").tag(2)
Text("Logo").tag(3)
Text("Canvas").tag(4)
}
.frame(width: 400)
.pickerStyle(.segmented)
ScrollViewReader { value in
ScrollView (.vertical, showsIndicators: false) {
ZStack {
RoundedRectangle(cornerRadius: 20)
// .backgroundStyle(.ultraThinMaterial)
.foregroundColor(.black)
.opacity(0.2)
.frame(width: 350, height:185)
// .foregroundColor(.secondary)
.id(1)
There are 2 things you are mixing here:
The tag modifier is to differentiate elements among certain selectable views. i.e. Picker TabView
You can't access the proxy reader from outside unless you make it available. In other words the tag in the Picker and the ScrollViewReader does not have a direct relationship, you have to create that yourself:
import SwiftUI
struct ScrollTest: View {
#State private var mainTab = 1
#State private var scrollReader: ScrollViewProxy?
var body: some View {
// Main Picker
Picker("MainTab", selection: $mainTab) {
Text("iP1").tag(1)
Text("iP2").tag(2)
Text("Logo").tag(3)
Text("Canvas").tag(4)
}
.frame(width: 400)
.pickerStyle(.segmented)
.onChange(of: mainTab) { mainTab in
withAnimation(.linear) {
scrollReader?.scrollTo(mainTab, anchor: .top)
}
}
ScrollViewReader { value in
ScrollView (.vertical, showsIndicators: false) {
ForEach(1...4, id: \.self) { index in
ZStack {
RoundedRectangle(cornerRadius: 20)
.foregroundColor(.black)
.opacity(0.2)
.frame(width: 350, height: 500)
Text("index: \(index)")
}
.id(index)
}
}
.onAppear {
scrollReader = value
}
}
}
}
We have a custom textfield defined in SwiftUI. This is the basic code for it:
var body: some View {
ZStack(alignment: .leading) {
RoundedRectangle(cornerRadius: Constants.cornerRadius, style: .continuous)
.stroke(isFocused ? Color.blue : hasWarning ? .red : .gray, lineWidth: Constants.lineWidth)
HStack {
Text(title)
.font(.body)
.foregroundColor(isFocused ? Color.blue : hasWarning ? .red : .gray)
.padding(.horizontal, text.isEmpty ? Constants.Padding.horizontalIsEmpty : Constants.Padding.horizontalIsNotEmpty)
.background(text.isEmpty ? Color.clear : background)
.padding(.leading, Constants.Padding.leading)
.offset(y: text.isEmpty ? Constants.Offset.isEmpty : -(frameHeight / Constants.Offset.isNotEmptyRatio))
.scaleEffect(text.isEmpty ? Constants.ScaleEffect.isEmpty : Constants.ScaleEffect.isNotEmpty, anchor: .leading)
}
HStack {
TextField("", text: $text, onEditingChanged: { inFocus in
self.isFocused = inFocus
})
.font(.body)
.padding(.horizontal, Constants.Padding.horizontal)
}
}
.frame(height: frameHeight)
.background(background)
.animation(.easeInOut(duration: Constants.Animation.easeInOut))
.padding(.top, Constants.Padding.top)
}
Currently there's no viewModel linked to this. Now we want to extend this component to be able to include one (or both of):
An internal button
An icon in the textfield itself
I want to avoid adding any logic into the view and so I initially created a viewModel that looks something like this:
struct InternalTextfieldButtonProperties {
let action: () -> Void
let labelText: String
}
class TextFieldFloatingWithBorderViewModel: ObservableObject {
let internalButtonProperties: InternalTextfieldButtonProperties?
let icon: Image?
var hasButton: Bool {
return internalButtonProperties != nil
}
var hasIcon: Bool {
return icon != nil
}
init(internalButtonProperties: InternalTextfieldButtonProperties? = nil, icon: Image? = nil) {
self.internalButtonProperties = internalButtonProperties
self.icon = icon
}
}
The idea being that you can initialise this and then use the viewModel properties within the view to display the a button and or icon. However, this all seems a bit counterproductive as the icon and button properties in the viewModel would still need to be optional, which means again unwrapping in the view, taking away some of the point of having the viewModel. Indeed, if no icon or button is required, you end up declaring a viewModel for no reason.
I wondered if there's a cleaner way of doing this?
I am just starting out with both Watch development and SwiftUI, and thought I would start with a simple Login Screen. I have made two buttons of two different styles. The strange thing is that my buttons have a strange red inner view to them and I am not sure why.
struct ContentView : View
{
var body: some View
{
VStack
{
Button( "Login")
{
}
.accentColor( .white)
.frame( idealHeight:50.0)
.padding( [.leading, .trailing], 10.0)
.background( Color.red)
.cornerRadius( 5.0)
Button( "Sign Up")
{
}
.accentColor( .red)
.frame( idealHeight:50.0)
.padding( [.leading, .trailing], 10.0)
.background( Color.white)
.cornerRadius( 5.0)
}
}
}
Can someone tell me what is going on here ?
Also if someone has reputation of 1500 can they please create WatchOS6 tag ?
Update: This works way better on the iPhone than the Watch, Buttons seem to work differently on the two devices. As pointed out by #MarkT you need to start out with a button style of plain. The issue with this is that it stops you using your own Button Styles.
You are only defining a background behind a "default" Button that's why it looks so wired.
Changing the button style to "plain" and apply the corner radius to the background will help. Of course you must adjust the background size by using padding to frame ...
Button( "Login")
{
}
.buttonStyle(PlainButtonStyle())
.padding(.horizontal, 60)
.padding(.vertical, 10)
.background(
Color.red
.cornerRadius( 5.0))
Update: As mentioned from d4Rk we have to use PlainButtonStyle()
This worked for me
HStack {
Button("Login")
{
}
.buttonStyle(BorderedButtonStyle(tint: .clear))
.foregroundColor(.white)
}
.background(Color.red)
.cornerRadius(5)
if its in a list try this as well
.listRowPlatterColor(Color.clear)
I believe that this is a result of using accentColor to define the colour of you text for the button.
You can substitute this for foregroundColor and achieve the same text colour but hopefully without the odd patterning you are currently experiencing.
With the changes your code would look like:
struct ContentView : View
{
var body: some View
{
VStack
{
Button( "Login")
{
}
.foregroundColor( .white)
.frame( idealHeight:50.0)
.padding( [.leading, .trailing], 10.0)
.background( Color.red)
.cornerRadius( 5.0)
Button( "Sign Up")
{
}
.foregroundColor( .red)
.frame( idealHeight:50.0)
.padding( [.leading, .trailing], 10.0)
.background( Color.white)
.cornerRadius( 5.0)
}
}
}
Unfortunately this doesn't entirely solve the issue.
As you can see we go from this:
to this:
Which is not ideal.
According to this documentation you should set the radius to 22 points (or 9 for scroll view)