I am not sure why this is happening.
In my application, I have
ViewController.swift
CustomUIView.swift
CustomUIView.xib
In my ViewController.swift
var customView: CustomUIView = NSBundle.mainBundle().loadNibNamed("CustomUIView", owner: self, options: nil).first as CustomUIView;
customView.setupControl();
self.view.addSubview(customView);
In my CustomUIView.swift I tried to change the properties of a UIButton created in the CustomUIView.XIB such as this
#IBOutlet weak var button: UILabel!
func setupControl()
{
label.frame = CGRect(x: 0 , y: 30, width: 320, height: 240); //THIS DOES NOT WORK
label.text = "BLABLABLA"; //THIS WORKS
}
I can only modify the property of the UIButton from the InterfaceBuilder.
Any thoughts on why this is happening?
Are you using Auto Layout? If yes, you can't set the frame, because the constraints will override the frame setting. To change the frame, you must set the constraints.
Related
Sorry in advance, this is a long question but I wanted to explain as good as I can.
I need to implement a walkthrough(first time launch guide) for the project, which will only be shown to user for the first time they launch the app.
I've implemented it by creating a .xib file, where I was just creating a view for each item I need to implement for the walkthrough by creating objects referring to .xib model.
But now I'm required to implement it without using .xib files, where I need to do it via storyboard. This time I've inserted a scrollView, and then I put another view inside it with the objects I'm going to need such as (labels,imageViews,buttons etc.) But it doesn't work, even though I can create all the objects by copying the view right under the scrollView. When I try to expand the width of the scrollView with all the views created so I can do paging, it doesn't create each view next to each other but only shows me the last object(view) in the simulator as they add up vertically, and I can't do no paging.
Now I provide some sample code to show how I try to implement this:
import UIKit
class DenemeViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var pageControl: UIPageControl!
#IBOutlet weak var repeatingView: UIView!
var viewArray = [UIView]()
override func viewDidLoad() {
super.viewDidLoad()
let temporaryView = repeatingView
temporaryView?.backgroundColor = .black
viewArray.append(temporaryView!)
let temporaryViewTwo = repeatingView
temporaryViewTwo?.backgroundColor = .blue
viewArray.append(temporaryViewTwo!)
pageControl.numberOfPages = viewArray.count
pageControl.currentPage = 0
view.bringSubview(toFront: pageControl)
setupScrollView(items: viewArray)
}
func setupScrollView(items: [UIView]) {
scrollView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
scrollView.contentSize = CGSize(width: view.frame.width * CGFloat(items.count), height: view.frame.height)
scrollView.isPagingEnabled = true
for i in 0..<items.count {
items[i].frame = CGRect(x: view.frame.width * CGFloat(i), y: 0, width: view.frame.width, height: view.frame.height)
scrollView.addSubview(items[i])
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageIndex = round(scrollView.contentOffset.x/view.frame.width)
pageControl.currentPage = Int(pageIndex)
}
}
As you can see I first create two different views in viewDidLoad by referring to "repeatingView" which is the outlet of the view inside scrollView on the storyboard. Then I return them in an array and try to implement scrollView's subviews with views.
I was expecting to see the scrollView starting with the view with black background and as I do the paging through right then the view with blue background should appear.
When I run this what I see is only the blue view, and I'm unable to do any paging or scrolling.
I'm trying to make UIViews which each contain different statements of text (In UITextViews). There can be a varying number of views and each statement can be different in length. I make these views using
let newView = DragView(heightOfView: ???, viewNumber: i, heightFromTop: currentHeightForThings)
In the DragView class I then access the statement using the viewNumber and put the statement in the text label in a nib file I've made.
My issue is I have nothing to put in heightOfView. The height I want is the height of the textLabel which varies depending on how many lines are in the textView for the statement. However I can't access this height because the textLabel isn't built yet.
Thanks in advance, I'm new to swift but want to learn fast so I apologise if I'm missing something obvious!
Heres the code I have in the class DragView
class DragView: UIView {
#IBOutlet var dragView: UIView!
#IBOutlet weak var statementLabel: UITextView!
var dropTarget: UIView?
var viewNumber: Int!
init(heightOfView: Int, viewNumber:Int, heightFromTop: Int) {
self.viewNumber = viewNumber
let startingPosition = CGRect(x: Int(widthCentre) - dragViewWidth / 2, y: heightFromTop, width: dragViewWidth, height: heightOfView)
super.init(frame: startingPosition)
NSBundle.mainBundle().loadNibNamed("DragView", owner: self, options: nil)
self.addSubview(self.dragView)
let movingView = MovingView(frame: startingPosition)
self.addSubview(movingView)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
Here the movingView is a subview I add over the view to move the view.
You can override the DragView's sizeThatFits method to have it return a height based on the statementLabel's height. You will have to first call sizeToFit on the textView which will set the height for that view, then return a height based on that.
override func sizeThatFits(size: CGSize) -> CGSize {
self.statementLabel.sizeToFit()
return CGSize(
width: self.frame.width,
height: self.statementLabel.frame.height)
}
Additionally, I would recommend looking into sizeThatFits and layoutSubviews if you are going to be doing programatic layout. The sizing and positioning of subviews should be taking place in layoutSubviews rather than init.
I have a xib that I've created in Xcode's interface builder. Inside the xib is a UIVisualEffectView w/ vibrancy. If I add a subview to the UIVisualEffectView in any capacity (either in interface builder or programmatically as you can see in the code below), then the subview is vibrant (as it should be) however the UIVisualEffectView is no where to be seen.
So the subviews of the UIVisualEffectView are the only elements visible on screen while the UIVisualEffectView itself is missing.
Before adding any subviews, the UIVisualEffectView appears perfectly fine onscreen.
How can I fix this?
import UIKit
class EmptyContentView: UIView {
#IBOutlet var visualEffectView: UIVisualEffectView!
override func awakeFromNib() {
var vibrantLabel = UILabel()
vibrantLabel.text = "Vibrant"
vibrantLabel.sizeToFit()
vibrantLabel.center = self.center
self.visualEffectView.contentView.addSubview(vibrantLabel)
}
}
Edit: Note, I am testing on a device. iPhone 6 plus running iOS8. In the simulator I see neither the subviews nor the UIVisualEffectView.
Here is how I am instantiating the nib's view.
var nibViews = NSBundle.mainBundle().loadNibNamed("EmptyContentView", owner: self, options: nil)
let emptyContentView = nibViews[0] as! EmptyContentView
emptyContentView.frame = CGRect(x: 0, y: 0, width: self.tableView.frame.size.width, height: self.tableView.frame.size.height)
self.tableView.addSubview(emptyContentView)
UIView.animateWithDuration(0.2, delay: 0, options: UIViewAnimationOptions.AllowUserInteraction, animations: { self.tableView.alpha = 1 }, completion: nil)
By the way, animating the tableView or not does not make a difference. The frame for the emptyContentView is also correct.
Note: Turning off vibrancy does fix the issue.
I have a UIBarButtonItem and a UIView containing two UITextField controls, all within a UIToolbar.
This is a screenshot of my storyboard: http://i.8px.co/x8eC.png.
I'd like to create something similar to this: http://i.8px.co/1hvY.png.
I'm trying to make the UIView and its children expand to fill the available horizontal space in the UIToolbar with Auto Layout. I don't know how to accomplish what I want.
I experimented with a dirty solution for the UIView and was able to have it size somewhat correctly.
view.width = toolBar.frame.width - button.width
// where view is the UIView, toolBar is the UIToolBar, and button is the UIBarButtonItem
I don't believe this is very elegant. This is done programmatically, the UIView doesn't conform to the standard UIToolbar margins, and the solution doesn't apply to the UITextFields.
I'm afraid you'd have to do this programmatically.
Try this :
self.toolBarview.frame = (CGRect) {.origin = self.toolBarview.frame.origin.x, self.toolBarview.frame.origin.y, .size = [UIScreen mainScreen].bounds.size.width - self.barButton.width - 40, self.toolBarview.frame.size.height};
Here toolBarview is the UIView which has the 2 UITextField's. 40 is the buffer value that you need to subtract to give the padding.
/* EDIT */
You should give the appropriate constraints to the UITextField as shown below:
"I'm trying to make the UIView and its children expand to fill the available horizontal space in the UIToolbar with Auto Layout" You can't. The UIView is in a UIBarButtonItem, and a UIBarButtonItem is not a view. So you can't use auto layout on it. You must set its width manually.
You can do this in many way,
Do these Constraints
Then create a sub class of UITextField, and do this code
class CustomTextField: UITextField {
override func textRectForBounds(bounds: CGRect) -> CGRect {
return CGRectInset(CGRectMake(65, 0, bounds.size.width-65, bounds.size.height) , 0 , 0 )
}
override func editingRectForBounds(bounds: CGRect) -> CGRect {
return CGRectInset(CGRectMake(65, 0, bounds.size.width-65, bounds.size.height) , 0 , 0 )
}
}
In storyboard/xib, Connect textField to your CustomTextField
Create outlet for 2 textFields
#IBOutlet weak var textField1: CustomTextField!
#IBOutlet weak var textField2: CustomTextField!
in viewDidLoad() method,
var label1 : UILabel = UILabel(frame: CGRectMake(5, (textField1.frame.height/2)-15, 100, 30))
label1.textColor = UIColor.lightGrayColor();
label1.text = "From:"
var label2 : UILabel = UILabel(frame: CGRectMake(5, (textField1.frame.height/2)-15, 100, 30))
label2.textColor = UIColor.lightGrayColor();
label2.text = "To:"
textField1.addSubview(label1)
textField2.addSubview(label2)
Then you will get output like...
Let me explain my problem here, I am working on a project in which I am having a xib file with a UIView. What I have done is, I created another UIView inside the same xib and I need to show that in my xib view in a button action using swift.
Note : If I tend to do this via programatically it is working fine but the problem while I am doing with my xib. (testview) is a view that I have created inside the xib.
class tableClass: UIViewController {
#IBOutlet var testview : UIView
override func viewDidLoad() {
super.viewDidLoad()
println(testview) **///// Return nil /////**
testview=UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200)) as UIView
println(testview) **///// Return nil /////**
self.view.bringSubviewToFront(testview)
self.view.addSubview(testview)
}
}
Thanks in Advance. Please let me know, your answers and valuable ideas.
I solved the above stated problem by initializing my UIView in ViewDidLoad method. Here, is the lines I wrote on my didLoad method
class tableClass: UIViewController {
#IBOutlet var testview : UIView = nil
override func viewDidLoad() {
super.viewDidLoad()
testview.frame = CGRectMake(0, 0, 0, 0)
self.view.addSubview(testview)
}}
After doing that, I can able to change the UIView frame anywhere from the class, like below. Happy Coding..
testview.backgroundColor = UIColor.greenColor()
testview.frame = CGRectMake(50, 50, 50, 50)