How to resize Text View in Swift - swift

I'm doing some work for the project(Newbie programmer) in SwiftUI.
I try to resize the textbox yet IDK how. Could anyone help me about this?
import SwiftUI
struct ContentView: View {
#Binding var document: NavKov20193123Document
var body: some View {
TextEditor(text: $document.text)
.foregroundColor(.gray)
.lineSpacing(3)
.allowsTightening(false)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView(document: .constant(NavKov20193123Document()))
}
}

you can use .frame(width: , height: )
struct ContentView: View {
var body: some View {
return Text("Hello world")
.font(.system(size: 50, weight: .bold))
.minimumScaleFactor(0.5)
.frame(width: 100, height: 100)
.background(Color.yellow)
}
}

Related

SwiftUI Tutorial: Scrumdigger Spacer() issue

I have been working through the SwiftUI Scrumdigger tutorial (https://developer.apple.com/tutorials/app-dev-training/getting-started-with-scrumdinger) and have reached Step 7 of "Creating a Card View". Here is where my experience deviates from what is presented by the tutorial.
Here is the code both I and the tutorial are using:
import SwiftUI
struct CardView: View {
let scrum: DailyScrum
var body: some View {
VStack(alignment: .leading) {
Text(scrum.title)
.font(.headline)
Spacer()
HStack {
Label("\(scrum.attendees.count)", systemImage: "person.3")
}
}
}
}
struct CardView_Previews: PreviewProvider {
static var scrum = DailyScrum.sampleData[0]
static var previews: some View {
CardView(scrum: scrum)
.background(scrum.theme.mainColor)
.previewLayout(.fixed(width: 400, height: 60))
}
}
Here is what I see:
And here is what the tutorial displays:
I have tried moving the Spacer() from line 9 to line 13 but the issue is the same.
Can reproduce without the reliance on the external Scrum data using this:
import SwiftUI
struct CardView: View {
//let scrum: DailyScrum
var body: some View {
VStack(alignment: .leading) {
Text("Title")
.font(.headline)
Spacer()
HStack {
Label("3", systemImage: "person.3")
}
}
}
}
struct CardView_Previews: PreviewProvider {
//static var scrum = DailyScrum.sampleData[0]
static var previews: some View {
CardView()
.previewLayout(.fixed(width: 400, height: 60))
}
}
Can anyone advise as to what might be going wrong here?

SwiftUI .overlay() causing data to be displayed incorrectly

I'm working on an app that calls an api and displays the data on 6 different cards. In the card view the data displays correctly. Once I place that view into another using .overlay() the UI is perfect but the data on each card is the same. Without .overlay() the data is correct but the UI is wrong. I've tried changing my ViewModel variable in the views to #EnvironmentObject, #StateObject, & #ObservedObject with no luck. I can't figure out if this is a bug or I am missing something. Any help is greatly appreciated.
This view displays data correctly:
import SwiftUI
struct TopActivityCardView: View {
// #EnvironmentObject var vm: ViewModel
#StateObject var vm = ViewModel()
var timePeriod = ""
var body: some View {
ZStack {
ScrollView{
ForEach(vm.fetch(), id: \.title) { item in
RoundedRectangle(cornerRadius: 20)
.foregroundColor(Color.darkBlue)
.frame(height: 120, alignment: .center)
.padding(.top, 80)
.overlay(
ActivityTitleView(activityTitle: item.title)
).overlay(
ActivityHoursView(workHours: item.timeframes.weekly.current)
).overlay(
ActivityEllipisView()
).overlay(
TimePeriodView(timePeriod: "Last Week", weeklyHrs:
item.timeframes.weekly.previous)
)
}
}
}
}
}
struct TopActivityCardView_Previews: PreviewProvider {
static var previews: some View {
TopActivityCardView()
.environmentObject(ViewModel())
}
}
This view is where the problem occurs:
import SwiftUI
struct RectCardView: View {
var colorArray: [(colorName: Color, imageName: String)] = [(Color.work, "icon-work"),
(Color.play, "icon-play"), (Color.study, "icon-study"), (Color.exercise, "icon-
exercise"), (Color.social, "icon-social"), (Color.selfCare, "icon-self-care")]
// #StateObject var vm = ViewModel()
#ObservedObject var vm = ViewModel()
var body: some View {
ZStack{
ScrollView{
ForEach(colorArray, id: \.imageName) { colorName, imageName in
RoundedRectangle(cornerRadius: 20)
.foregroundColor(colorName)
.frame(height: 110, alignment: .center)
.overlay(
Image(imageName)
.brightness(-0.2)
.frame(width: 60, height: 20, alignment: .topLeading)
.offset(x: 103, y: -60)
).clipped()
/// If I take .overlay() off the cards display correct data but UI is
not correct.
/// With overlay UI is correct but data on cards is all the same.
.overlay{
TopActivityCardView()
.padding(.top, -40)
}
.padding(.top, 20)
}
}
}
}
}
struct RectCardView_Previews: PreviewProvider {
static var previews: some View {`enter code here`
RectCardView()
.environmentObject(ViewModel())
}
}
In TopActivityCardView, you are making a new view model (#StateObject var vm = ViewModel()).
It isn't using the same view model as RectCardView, so the data is different.
You could pass the view into TopActivityCardView by using an environment object:
// code…
struct TopActivityCardView: View {
#EnvironmentObject var vm: ViewModel
// more code…
}
.overlay{
TopActivityCardView()
.environmentObject(vm)
.padding(.top, -40)
}

Problem to see Live Preview Cannot find a View struct in scope SwiftUI

When I want to load or call a view into another view, I have an error, but I can run simulator and see the app works fine; it just doesn't let me see Live Preview in Xcode.
The error I have:
Cannot find 'HomeTemplate' in scope
Sample code:
struct HomeController: View {
var body: some View {
HStack {
HomeTemplate()
}
}
}
struct HomeController_Previews: PreviewProvider {
static var previews: some View {
HomeController()
}
}
And HomeTemplate file:
import SwiftUI
struct HomeTemplate: View {
var body: some View {
ScrollView {
VStack {
Text("Your Daily")
.font(.system(size: 25, weight: .bold))
.foregroundColor(Color.secondary)
.frame(maxWidth: .infinity, alignment: .leading)
Text("Recommendation")
.font(.system(size: 25, weight: .bold))
.foregroundColor(Color.primary)
.frame(maxWidth: .infinity, alignment: .leading)
}
.padding(.horizontal, 22)
.padding(.top, 30)
ScrollViewListSlideStyleOne()
}
}
}
struct HomeTemplateView_Previews: PreviewProvider {
static var previews: some View {
HomeTemplate()
}
}
Why doesn't it let me call a struct or class wherever I want? I saw the other similar questions, but they just import SwiftUI, and it works for them, but I added it before.
By the way, I uploaded my project on GitHub and you can access to it:
https://github.com/shahryarjb/MishkaCmsiOS

How to call a view with a specific size?

I have a question about views in swiftui.
I have created a file CircleView which shows me a circle and a text in the middle. Additionally I have created a list in ContentView and a DetailView for details.
I now use the created circle in the list and on the detail view. Unfortunately the size of the circle is defined in the CircleView and I don't know how to change it individually so that it is displayed small in the list and uses the full width on the detail view.
So how can I change the size of a view individually?
Here is my code
CircleView:
struct CircleView: View {
var body: some View {
ZStack{
Circle()
.fill(Color.blue)
.frame(width: 250, height: 250)
Text("VIEW")
.frame(width: 100, height: 100)
.font(.largeTitle)
.foregroundColor(.white)
}
}
}
ContentView:
struct ContentView: View {
var body: some View {
NavigationView {
List{
NavigationLink(destination: DetailsView()) {
HStack{
Text("Hello")
Spacer()
CircleView()
}
}.navigationTitle("Home")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
DetailsView:
struct DetailsView: View {
var body: some View {
VStack{
Text("Hello, World!")
.padding(10)
CircleView()
}
}
}
You should remove the set frame from your view and apply it when using your view.
Your code edited:
struct Sample: View {
var body: some View {
NavigationView {
List{
NavigationLink(destination: DetailsView()) {
HStack{
Text("Hello")
Spacer()
CircleView()
.frame(width: 100 , height: 100) // <-- Update frame here
}
}.navigationTitle("Home")
}
}
}
}
struct CircleView: View {
var body: some View {
ZStack{
Circle()
.fill(Color.blue)
Text("VIEW")
.font(.largeTitle)
.foregroundColor(.white)
}
}
}
struct Sample_Previews: PreviewProvider {
static var previews: some View {
Sample()
}
}
struct DetailsView: View {
var body: some View {
VStack{
Text("Hello, World!")
.padding(10)
CircleView().padding()
}
}
}

SwiftUI: changing view using "if else"

I’m trying to change a view based on a selection made with a button. I’m using Combine and SwiftUI.
I create a view router class with a #Published var:
import Foundation
import SwiftUI
import Combine
class ViewRouter: ObservableObject {
#Published var currentView = "folder"
}
I have my button struct:
import SwiftUI
import Combine
struct MultiButton: View {
#ObservedObject var viewRouter = ViewRouter()
#State var showButton = false
var body: some View {
GeometryReader { geometry in
ZStack{
// open multi button
Button(action: {
withAnimation {
self.showButton.toggle()
}
}) {
Image(systemName: "gear")
.resizable()
.frame(width: 40, height: 40, alignment: .center)
}
if self.showButton {
Multi()
.offset(CGSize(width: -30, height: -100))
}
}
}
}
}
struct MultiButton_Previews: PreviewProvider {
static var previews: some View {
MultiButton()
}
}
struct Multi: View {
#ObservedObject var viewRouter = ViewRouter()
var body: some View {
HStack(spacing: 10) {
ZStack {
Button(action: {
self.viewRouter.currentView = "folder"
debugPrint("\(self.viewRouter.currentView)")
}) {
ZStack{
Circle()
.foregroundColor(Color.blue)
.frame(width: 70, height: 70)
Image(systemName: "folder")
.resizable()
.aspectRatio(contentMode: .fit)
.padding(20)
.frame(width: 70, height: 70)
.foregroundColor(.white)
}.shadow(radius: 10)
}
}
Button(action: {
self.viewRouter.currentView = "setting"
debugPrint("\(self.viewRouter.currentView)")
}, label: {
ZStack {
Circle()
.foregroundColor(Color.blue)
.frame(width: 70, height: 70)
Image(systemName: "gear")
.resizable()
.aspectRatio(contentMode: .fit)
.padding(20)
.frame(width: 70, height: 70)
.foregroundColor(.white)
}.shadow(radius: 10)
})
}
.transition(.scale)
}
}
And the contentView:
import SwiftUI
import Combine
struct ContentView: View {
#ObservedObject var viewRouter = ViewRouter()
var body: some View {
VStack{
MultiButton()
if viewRouter.currentView == "folder" {
Text("folder")
} else if viewRouter.currentView == "setting"{
Text("setting")
}
}
}
}
Why is my text is not changing from the folder to setting the base when the button is pressEd?
The var is #Published; it should publish the change and update the main view.
Did I miss something?
You have multiple instances of ViewRouter with each view having its own instance. If you change that instance, the other instances are not going to change.
To solve this, you either have to pass one instance around manually:
struct MultiButton {
#ObservedObject var viewRouter: ViewRouter
...
}
struct ContentView {
#ObservedObject var viewRouter = ViewRouter()
var body: some View {
VStack {
MultiButton(viewRouter: self.viewRouter)
...
}
}
}
Or you can declare it as an environment object:
struct MultiButton {
#EnvironmentObject var viewRouter: ViewRouter
...
}
And then inject it for example when you create your view hierarchy in your scene delegate:
let contentView = ContentView()
.environmentObject(ViewRouter())
Note that when injecting the environment object in the scene delegate, it will not be available in every preview of a view that uses the ViewRouter, unless you manually inject it there as well:
static var previews: some View {
ContentView()
.environmentObject(ViewRouter())
}