I have an array of buttons which I have added within a stackview, I need to add this stackView in one of my subview which is in another parentStackView.
This is my code:
let innerStackView = UIStackView(arrangedSubviews: buttonViews(withTitleArray: buttonTitleArray, numberArray: ButtonTagArray))
innerStackView.backgroundColor = UIColor.green
innerStackView.axis = .vertical
innerStackView.distribution = .fillEqually
innerStackView.alignment = .fill
innerStackView.spacing = 5
innerStackView.translatesAutoresizingMaskIntoConstraints = false
mainView.bottomView.backgroundColor = UIColor.red
mainView.bottomView.addSubview(innerStackView)
NSLayoutConstraint.activate([
mainView.leadingAnchor.constraint(equalTo: innerStackView.leadingAnchor),
mainView.trailingAnchor.constraint(equalTo: innerStackView.trailingAnchor),
mainView.widthAnchor.constraint(equalTo: innerStackView.widthAnchor),
mainView.heightAnchor.constraint(equalTo: innerStackView.heightAnchor)])
mainView.alpha = 1
mainView.clipsToBounds = true
parentstackView.addArrangedSubview(mainView)
self.view.layoutIfNeeded()
The issue is that even though I can see the mainView in my parentStackView, the inner stackview is not visible. I can't seem to understand why?
Any help would be appreciated.
okay, So I couldn't find a solution programmatically, I ended up making the bottomView in the interface builder and binding it with the mainview with the help of constraints.That did the trick for me.
Related
I'm using fscalender on my project which I have to use both month scope and week scope on different view controller.so when I'm using week scope date title size is getting smaller, but when I increase the view height its getting perfect.but my view should have an fixed size so how can I fix this problem.
this is my calendar now
here I converted the round background to rectangle by
calendarObj.appearance.borderRadius = 0
The above week title is implemented with stackview.
This is actually I want
the rectangle border is not showing full.How to resolve this?Im new to this iOS
I Tried This On A view, I have Added only Few Lines, an it is working as you want.
calendarView.dataSource = self
calendarView.delegate = self
calendarView.scrollDirection = .vertical
calendarView.scope = .week
calendarView.backgroundColor = .clear
calendarView.allowsMultipleSelection = false
calendarView.appearance.selectionColor = .none
calendarView.appearance.borderSelectionColor = .red
calendarView.appearance.todayColor = .clear
calendarView.appearance.titleTodayColor = .black
calendarView.appearance.weekdayTextColor = .black
calendarView.appearance.borderRadius = 0.2
I Hope This Will Help.
I have a vertical stackView.
bodyStackView.translatesAutoresizingMaskIntoConstraints = false
bodyStackView.axis = .vertical
bodyStackView.alignment = .fill
bodyStackView.distribution = .fill
bodyStackView.spacing = 8.0
bodyStackView.backgroundColor = .yellow
and two/three views get added to it.
bodyStackView.addArrangedSubview(titleStackView)
bodyStackView.addArrangedSubview(priceStackView)
bodyStackView.addArrangedSubview(subscriptionInEligibleLabel)
titleStackView.setContentHuggingPriority(.defaultHigh, for: .vertical)
priceStackView.setContentHuggingPriority(.defaultLow, for: .vertical)
I want the last or the bottom-most view to stretch.
I have set the "ContentHuggingPriority", and yet the first or the top-most view is getting stretched.
How do we control this?
It's not clear why you have 3 stack views in your bodyStackView, but assuming you have a valid reason...
You need to set the Content Hugging Priority on the labels, not on the stack views.
I'm trying to setup a stackview in the middle of the screen with a padding of 20 to the left an right. Inside, I want to place two custom UIViews, but I don't quit understand how to do it. I tried giving the UIViews their respective Height's and Width's but I got nothing.
I believe the stack view has all the correct constraints. Here's the code:
func setupTeamViews() {
view.addSubview(teamsStackView)
teamsStackView.distribution = .fill
teamsStackView.axis = .vertical
teamsStackView.spacing = 20
teamsStackView.alignment = .fill
NSLayoutConstraint.activate([
teamsStackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
teamsStackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
teamsStackView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
teamsStackView.heightAnchor.constraint(equalToConstant: 420)
])
let height = CGFloat((teamsStackView.frame.height / 2) - 20)
let width = CGFloat((teamsStackView.frame.width - 20))
firstTeamView = ATTeamView(width: width, height: height)
firstTeamView.changeColor(color: .lightBlue)
firstTeamView.setTeamName(name: "Tobias")
firstTeamView.setNewPoints(points: "0")
secondTeamView = ATTeamView(width: width, height: height)
secondTeamView.changeColor(color: .white)
secondTeamView.setTeamName(name: "Valen")
secondTeamView.setNewPoints(points: "0")
teamsStackView.addArrangedSubview(firstTeamView)
teamsStackView.addArrangedSubview(secondTeamView)
}
How does a stackview work with UIview's? As far I understand, UIViews don't have intrinsicContentSize, but I don't know how to deal with that.
In stead of doing it programmatically you can add two container views attach them to your view controller, and then active them with the alpha.
This will make constraints easier and you can still program anything extra you would like
myView1.alpha = 1 // activate
myView2.alpha = 0 // deactivate
My code wasn't working because I've forgotten to set teamsStackView.translatesAutoresizingMaskIntoConstraints = false
In above screen, you can see I am using a UIStackView to fill radio buttons vertically. problem is my radio buttons not utilising the full width of UIStackView when I use stackV.alignment = .leading it shows label as "dis..lified" instead of disqualified.
UISTackView Code
let ratingStackView : UIStackView = {
let stackV = UIStackView()
stackV.translatesAutoresizingMaskIntoConstraints = false
stackV.backgroundColor = UIColor.yellow
stackV.axis = .vertical
stackV.distribution = .fillEqually
stackV.alignment = .leading
return stackV
}()
Layout of UIStackView
func setupView(){
view.addSubview(ratingStackView)
ratingStackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
ratingStackView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor,constant: 8).isActive = true
ratingStackView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
ratingStackView.heightAnchor.constraint(equalToConstant: 200).isActive = true
//Add radio buttons to stackview
for ratingButton in ratingRadioButtons{
ratingStackView.addArrangedSubview(ratingButton)
}
}
what property I need to set to utilize full width can you please tell I am new to the Swift for radio buttons. I am using DLRadioButton.
To get this working, you need to make following changes in the layout:
1. Set UIStackView's alignment property to fill, i.e.
stackV.alignment = .fill
2. Set UIButton's Horizontal Alignment to left wherever you are creating the RadioButton either in .xib file or through code.
In .xib, you can find the property in interface here:
if you are creating the button using code, use the following line of code:
ratingButton.contentHorizontalAlignment = .left
Let me know if you still face the issue. Happy coding..🙂
Leave alignment with its default value, i.e. .fill – this stretches arranged views in a direction perpendicular to the stack’s axis.
Actually, I suspect that if you are using .leading alignment and do not specify widths of nested controls you are getting auto layout warnings during runtime (could be checked in Visual Debugger in Xcode).
Try proportional distribution.
One more thing to try...Reduce the content hugging priority of the labels.
I'm creating a view programmatically and need to set constraints between two labels. I recently just discovered NSLayoutAnchor and feel it would be a good choice to use it but I'm unsure how to create constraints between two different things (ie labels, imageViews, etc). I know a general setup will look something like this:
let codedLabel:UILabel = UILabel()
codedLabel.frame = CGRect(x: 100, y: 100, width: 200, height: 200)
codedLabel.textAlignment = .center
codedLabel.text = alertText
codedLabel.numberOfLines=1
codedLabel.textColor=UIColor.red
codedLabel.font=UIFont.systemFont(ofSize: 22)
codedLabel.backgroundColor=UIColor.lightGray
self.contentView.addSubview(codedLabel)
codedLabel.translatesAutoresizingMaskIntoConstraints = false
codedLabel.heightAnchor.constraint(equalToConstant: 200).isActive = true
codedLabel.widthAnchor.constraint(equalToConstant: 200).isActive = true
codedLabel.centerXAnchor.constraint(equalTo: codedLabel.superview!.centerXAnchor).isActive = true
codedLabel.centerYAnchor.constraint(equalTo: codedLabel.superview!.centerYAnchor).isActive = true
How would you set up constraints in between two labels?
Let's say you have two UIViews you wish to lay out horizontally in one of two ways:
View #1 is 20 points from the leading edge of the superview's margin or safe area and View #2 is another 20 points from view #1. (Think of a left-justified row of buttons.)
Both views are to be centered, with equal spacing before/between/after each view. (Think of two buttons spaced equally apart and centered.)
For example #1 the code would be:
// #1
let view1 = UIView()
view1.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(view1)
let view2 = UIView()
view2.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(view2)
// #2
let margins = view.layoutMarginsGuide
view.addLayoutGuide(margins)
view1.leadingAnchor.constraint(equalTo: margins.leadingAnchor, constant: 20).isActive = true
// #3
view2.leadingAnchor.constraint(equalTo: view1.trailingAnchor, constant: 20).isActive = true
// #4
view1.widthAnchor.constraint(equalToConstant: 100).isActive = true
view2.widthAnchor.constraint(equalToConstant: 100).isActive = true
Comment #1: Note that you do not need to give each view a frame, but you do need to set the auto-resizing mask to false. This is a mistake many new coders forget.
Comment #2: All UIViewController main views have a layoutMarginGuide that yield standard margins both vertically and horizontally (and in iOS 11, particularly for iPhone X, there is a new safeAreaLayoutGuide for vertical alignment). I've set the leading edge of view1 to be the leading edge of the margin with an additional constant of 20 points from it.
Comment #3: Just like I related view1 to the margin, I'm relating view2 to view1, but this time the leading edge ofview2is 20 points from theview1` trailing edge.
Comment #4: The last thing you need to do for horizontal placement is to give each view a width. In this case I wanted both to be 100 points.
Example #2 pretty much uses the same code as example #1, so I'll note the key differences only:
let view1 = UIView()
view1.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(view1)
let view2 = UIView()
view2.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(view2)
let margins = view.layoutMarginsGuide
view.addLayoutGuide(margins)
// #1
let spacer1 = UILayoutGuide()
view.addLayoutGuide(spacer1)
let spacer2 = UILayoutGuide()
view.addLayoutGuide(spacer2)
let spacer3 = UILayoutGuide()
view.addLayoutGuide(spacer3)
// #2
spacer.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
view1.leadingAnchor.constraint(equalTo: spacer1.trailingAnchor).isActive = true
spacer2.leadingAnchor.constraint(equalTo: view1.trailingAnchor).isActive = true
view2.leadingAnchor.constraint(equalTo: spacer2.trailingAnchor).isActive = true
spacer3.leadingAnchor.constraint(equalTo: view2.trailingAnchor).isActive = true
spacer3.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
// #3
view1.widthAnchor.constraint(equalToConstant: 100).isActive = true
view2.widthAnchor.constraint(equalToConstant: 100).isActive = true
spacer1.widthAnchor.constraint(equalTo: spacer2.widthAnchor).isActive = true
spacer2.widthAnchor.constraint(equalTo: spacer3.widthAnchor).isActive = true
Comment #1: In iOS 9 Apple introduced the concept of UILayoutGuides. Before this, to create "spacers" you had to actually create an invisible UIView and add it as a subview (with all the overhead associated with it). Layout guides "act" like views but do not have that overhead.
Comment #2: The horizontal sequence if "margin...spacer1...view1...spacer2...view2...spacer3...margin". Note that I'm not using any constants, as I wish to let the layout engine give equal spacing.
Comment #3: While I am giving width values for both views, I am not with the spacers. Instead, I am declaring their widths to be equal.
Please note that I've only worked with horizontal constraints. For auto layout to work, you also need to declare vertical constraints too. Most of the concepts are the same... instead of leading/trailing, centerX, and width anchors you have top/bottom, centerY, and height ones. BUT! Starting with iOS 11 you now have a safeAreaLayoutGuide that you should be using instead of layoutMarginsGuide. This only applies to vertical! That's why I separated things. Here's the code I use to work with vertical alignment:
let layoutGuideTop = UILayoutGuide()
let layoutGuideBottom = UILayoutGuide()
view.addLayoutGuide(layoutGuideTop)
view.addLayoutGuide(layoutGuideBottom)
if #available(iOS 11, *) {
let guide = view.safeAreaLayoutGuide
layoutGuideTop.topAnchor.constraintEqualToSystemSpacingBelow(guide.topAnchor, multiplier: 1.0).isActive = true
layoutGuideBottom.bottomAnchor.constraintEqualToSystemSpacingBelow(guide.bottomAnchor, multiplier: 1.0).isActive = true
} else {
layoutGuideTop.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor).isActive = true
layoutGuideBottom.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor).isActive = true
}
Now you have layoutGuideTop and layoutGuideBottom that should work regardless of what iOS version is running.