#IBOutlet weak var result: UILabel!
#IBOutlet weak var testview: UIView!
override func viewDidLoad() {
super.viewDidLoad()
testview.layer.shadowColor = UIColor.systemGray.cgColor
testview.layer.shadowOpacity = 0.6
testview.layer.shadowOffset = .zero
testview.layer.shadowRadius = 5
testview.layer.shadowPath = UIBezierPath(rect: testview.bounds).cgPath
testview.layer.shouldRasterize = true
testview.layer.rasterizationScale = UIScreen.main.scale
testview.addSubview(result)
}
After I add result to testview as a subview it's disappeared.
Your Storyboard already added result into the view hierarchy so when you add it again the frame stays the same but the point of reference changes since the superview is now testView so in your case it's going beyond the visible bounds. If you want the UILabel to be a subview of the testView I'd recommend making that change directly on the Storyboard, creating the UILabel programmatically instead of using Storyboards/IBOutlets or updating the frame of the label after adding it to testView.
Related
I'm trying to cope with iPhone X with inputAccessoryView. I've added a view to my ViewController like so:
CustomView
I've defined an outlet and attached to it. Returned the same view as inputAccessoryView like so:
class ViewController: UIViewController {
#IBOutlet weak var textFieldContainer: UIView!
override var inputAccessoryView: UIView? {
return textFieldContainer
}
override var canBecomeFirstResponder: Bool {
return true
}
override func viewDidLoad() {
super.viewDidLoad()
textFieldContainer.autoresizesSubviews = true
}
}
I've made sure to add constraints relative to safe area. Here are my constraints:
Constraints
Adjusted autoResizingMask in SB like so:
AutoResizingMask
However, it's still not working. Here's the output:
Output
What did I miss?
Unlike for table view cells, there is no support for dynamic height calculation in input accessory views, as far as I know.
You could use a fixed height for the accessory view.
But I assume, that you want just to change either top, bottom, or height constraint in interface builder and the change is reflected after the next build.
What you could do is, to use a custom view class where you connect your top, bottom and height constraints.
Then override intrinsicContentSize and return the sum of the three constraint constants.
class TextFieldContainer: UIView {
#IBOutlet weak var topConstraint: NSLayoutConstraint!
#IBOutlet weak var bottomConstraint: NSLayoutConstraint!
#IBOutlet weak var heightConstraint: NSLayoutConstraint!
override var intrinsicContentSize: CGSize {
let contentHeight =
self.topConstraint.constant
+ self.heightConstraint.constant
+ self.bottomConstraint.constant
return CGSize(width: UIScreen.main.bounds.width, height: contentHeight)
}
}
Your layout hierarchy could be simplified and look like this:
The autoresizing mask could look like this:
The final result would behave like the following then:
You're giving textfield height and also bottom constraint, try to remove bottom constraint for textfield
I have a UIViewScroll(background color is blue) in view controller. I need a UIView(background color is white) that were from Xib. The Xib view has a UILabel(background color is green) with constraints. Now, the problem is UILabel constraints not applied after adding it to scrollView. How to add UIView without loss of constraints? Refer following screenshots and code.
Note:
I need to just update constraints of the sub views of the UIView without using IBOutlets of NSLayoutConstraints.
UIView on Xib:
Code:
class ViewController: UIViewController {
#IBOutlet var scrollView: UIScrollView!
var profileView:UIView!
override func viewDidLoad() {
super.viewDidLoad()
self.profileView = UINib.init(nibName: "ProfileView", bundle: nil).instantiate(withOwner: self)[0] as! UIView
self.scrollView.addSubview(self.profileView)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.profileView.layer.frame.size = CGSize(width: self.scrollView.frame.width, height: self.profileView.frame.height)
self.profileView.layer.position = CGPoint(x: self.scrollView.frame.width/2, y: (self.profileView.frame.height/2)+10)
}
}
Output:
Update: More Information
I am aware to set contentSize of the scrollView. I used layer properties of UIView for manipulating height and width of the UIView. Instead of changing height and width also I need to update constraints of the sub views of UIView.
This is an example for understanding. But, In real I will be add more views like that.
Github Repository :
https://github.com/RAJAMOHAN-S/ScrollViewTest
Required output:
Your best bet is to set the constraint of self.profileView programmatically, I've added an example below to get you started.
class TestVC: UIViewController {
#IBOutlet var scrollView: UIScrollView!
private var profileView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
self.profileView = UINib.init(nibName: "ProfileView", bundle: nil).instantiate(withOwner: self)[0] as! UIView
self.configureProfileView()
}
private func configureProfileView() -> Void {
self.profileView.translatesAutoresizingMaskIntoConstraints = false
self.scrollView.addSubview(self.profileView)
self.profileView.widthAnchor.constraint(equalTo: self.scrollView.widthAnchor).isActive = true
self.profileView.heightAnchor.constraint(equalToConstant: 50.0).isActive = true
// Pin the profile view to the top of the scrollView
self.profileView.topAnchor.constraint(equalTo: self.scrollView.topAnchor).isActive = true
}
}
More information can be found here too: https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/ProgrammaticallyCreatingConstraints.html
I want to add a few view in scrollview. But I dont want to this view programmatically. I want to create with storyboard. This view include an image. I added scrollview and added to view. But in scrollview I just showing my last view. I want to 2 view and 2 image like my view. How can i fix this?
This is my code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var mainScrollView: UIScrollView!
var imageArray = [UIImage]()
#IBOutlet weak var myView: UIView!
#IBOutlet weak var imgv: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
imageArray = ["image","image2"]
for i in 0..<imageArray.count{
mainScrollView.contentSize.width = mainScrollView.frame.width * CGFloat(i + 1)
myView.layer.frame.size.width = myView.frame.width * CGFloat(i + 1)
imgv.image = imageArray[i]
mainScrollView.addSubview(myView)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
This is storyboard and controller looks like
You are having an issue with constraints from what I see and that is why you might not see every element that you put on your storyboard. You need to correct those errors for everything to show up correctly in your scrollview. Keep in mind, you need to tell the scrollview what its height and width should be in the storyboard. They need to be defined in some way. This is a common mistake when working with scrollviews.
You can put a view in your scrollview and define its height and width property. You can set its width to be equal to the screen's width and you can set a constant for your height.
These are my codes
//My UIViews
#IBOutlet weak var UIVIewFirst: UIView!
#IBOutlet weak var UIViewSecond: UIView!
#IBOutlet weak var UIViewThird: UIView!
#IBOutlet weak var middleViewHeightConstraint: NSLayoutConstraint!
#IBOutlet weak var ViewThirdHeight: NSLayoutConstraint!
There is a button to show and hide the view as;
#IBAction func infoClicked(sender: SSRadioButton) {
if UIViewSecond.hidden {
sender.selected = false
UIViewSecond.hidden = false
self.middleViewHeightConstraint.constant = 134
} else {
sender.selected = true
UIViewSecond.hidden = true
self.middleViewHeightConstraint.constant = 0
self.ViewThirdHeight.constant = 180
}
}
the vertical gap between each view is 10. After hiding the view the gap becomes 20. But i need it to set it 10 between third and second view. Even though i set the third view height constant to any number it does not changes it position.Can anyone suggest why is this happening??
Constraints ignore the hidden property.
If possible for your requirements, embedd your views within a UIStackView.
See this example.
You need to take the outlet connection of the vertical spacing constraint between either First-Second or Second-Third views. Also if you want to hide/show only Second view, you don't need to do any changes to Third View height constraint.
Say For example, we take the outlet of vertical spacing between First and Second views, then:
#IBOutlet weak var UIVIewFirst: UIView!
#IBOutlet weak var UIViewSecond: UIView!
#IBOutlet weak var middleViewHeightConstraint: NSLayoutConstraint!
#IBOutlet weak var verticalSpacingConstraint: NSLayoutConstraint!
#IBAction func infoClicked(sender: UIButton)
{
if UIViewSecond.hidden
{
sender.selected = false
UIViewSecond.hidden = false
self.middleViewHeightConstraint.constant = 134
self.verticalSpacingConstraint.constant = 10
}
else
{
sender.selected = true
UIViewSecond.hidden = true
self.middleViewHeightConstraint.constant = 0
self.verticalSpacingConstraint.constant = 0
}
}
Below are the screenshots of output:
1. When button is not selected
2. When button is selected
You have not tell your view to update the view with the new constraint, you have to call this code:
self.view.layoutIfNeeded()
firstView
| gap = 10
secondView
| gap = 10
thirdView
after removing secondView
firstView
| gap = 10
---------- height = 0
| gap = 10
thirdView
so the gap becomes 20
try to add constraint programmatically after hiding the view or decrease any one gap.
Try to change the frame of the view instead of changing the constraint, also do view.layoutIfNeeded after making any changes.
So I have a self made menu bar at the bottom of my ViewController that I need to keep constrained to the bottom of the screen. Between the navigation bar and the bottom bar I want a scroll view so I inserted a UIScrollView and within that scroll view I put a UIView. I did this because I was getting an error that was addressed with this thread:
UIScrollView Scrollable Content Size Ambiguity
So I have some labels that adjust in size based upon the text being used for the labels. I want the UIScrollView and also the associated UIView to adjust based upon how long the UILabels are. Right now I have it where the labels go below the bottom bar but the view isn't scrolling. Here is my code:
//
// ItemViewController.swift
//
import UIKit
import Parse
class ItemViewController: UIViewController {
#IBOutlet weak var menuButton: UIButton!
#IBOutlet weak var mainImage: UIImageView!
#IBOutlet weak var innerView: UIView!
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var heading1: UILabel!
#IBOutlet weak var body1: UILabel!
#IBOutlet weak var heading2: UILabel!
#IBOutlet weak var body2: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
for var y = 0; y < detailsHeadings.count; y++ {
switch y {
case 0:
heading1.text = detailsHeadings[y]
body1.text = details[heading1.text!]
let numLines = calcLines(body1.text!)
body1.numberOfLines = numLines!
break;
case 1:
heading2.text = detailsHeadings[y]
body2.text = details[heading2.text!]
let numLines = calcLines(body2.text!)
body2.numberOfLines = numLines!
break;
default:
break;
}
}
//none of the below worked
scrollView.sizeToFit()
scrollView.sizeThatFits(CGSize(width: 310, height: 700))
innerView.sizeThatFits(CGSize(width: 310, height: 700))
innerView.frame = CGRect(x: 0, y: 0, width: 320, height: 700)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func calcLines(textString: String) -> Int? {
let text = textString
// cast text to NSString so we can use sizeWithAttributes
var myText = text as NSString
//Set attributes
var attributes = [NSFontAttributeName : UIFont.systemFontOfSize(12)]
//Calculate the size of your UILabel by using the systemfont and the paragraph we created before. Edit the font and replace it with yours if you use another
var labelSize = myText.boundingRectWithSize(CGSizeMake(body1.bounds.width, CGFloat.max), options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: attributes, context: nil)
//Now we return the amount of lines using the ceil method
var lines = ceil(CGFloat(labelSize.height) / body1.font.lineHeight)
println(lines)
let linesInt: Int = Int(lines)
return linesInt
}
}
Does anyone have any idea how to achieve this? Any help would be greatly appreciated.
Try these steps:
Set all leading, trailing, top, and bottom constraints of your label to its superview and the superview's to the scrollView
Set your label's number of lines to 0 (unlimited)
Assuming that you're using autolayout since you're referring to UIScrollView content size ambiguity