Swift - Center multiple UILabel in different Y Positions - ios

I'm new to Swift and I try to make my first iOS app.
I have a problem with UILabels.
Made one which is centered (x and y) - its in the middle of the frame which is perfect.
//UILabel1 (works)
Level = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 100))
Level.center = (self.view?.center)!
Level.textAlignment = NSTextAlignment.Center
Now I have 2 more, which I want in the center of x, but y should be higher so that they are higher on the screen.
I can center them like Level .. That works, but if I try to change "y" (in CGRect()) or if I delete the .center (self.view?.center)! it just disappears of the screen.
GeschwindigkeitUILabel = UILabel(frame: CGRect(x: 0, y: 0, width: 300, height: 50))
GeschwindigkeitUILabel.center = (self.view?.center)!
Regel = UILabel(frame: CGRect(x: 0, y: 0, width: 300, height: 50))
Regel.center = (self.view?.center)!
How can I make GeschwindigkeitUILabel and Regel in the center of x but with a higher y value?
Tried self.view.height / 2 + 150 and things like that too, but then I can't see the label at all.

Updated Answer:
Instead of calculating frames, you can do it pretty easily using Auto layouts.
I have done demo project for your scenario, and below is the View it looks like (I have turned on the ShowViewFrame):
Here are the constraints i have used to make this:
let topLabel = UILabel()
topLabel.translatesAutoresizingMaskIntoConstraints = false
topLabel.text = "TopLabel"
topLabel.textAlignment = NSTextAlignment.Center
let middleLabel = UILabel()
middleLabel.translatesAutoresizingMaskIntoConstraints = false
middleLabel.text = "MiddleLabel"
middleLabel.textAlignment = NSTextAlignment.Center
let bottomtLabel = UILabel()
bottomtLabel.translatesAutoresizingMaskIntoConstraints = false
bottomtLabel.text = "BottomLabel"
bottomtLabel.textAlignment = NSTextAlignment.Center
self.view.addSubview(topLabel)
self.view.addSubview(middleLabel)
self.view.addSubview(bottomtLabel)
//Ideally we should create dictionary for metrics and view to increase the code readability.
//Metrics are used specify width, height, spacing between views.
let metrics = ["spacingBetweenMiddleLabelAndTopLabel" : 25, "spacingBetweenMiddleLabelAndBottomLabel": 25]
//Views we provide the subview for which we are setting the constraints
let views = ["topLabel": topLabel, "middleLabel": middleLabel, "bottomtLabel": bottomtLabel]
//Placing middleLabel at the centre of screen Horizontal
let centreXMiddleLabel:NSLayoutConstraint = NSLayoutConstraint(item: middleLabel, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0);
//Placing middleLabel at the centre of screen Vertical
let centreVMiddleLabel:NSLayoutConstraint = NSLayoutConstraint(item: middleLabel, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0);
//Placing topLabel at the centre of screen Horizontal
let centreXTopLabel:NSLayoutConstraint = NSLayoutConstraint(item: topLabel, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0);
//Placing bottomtLabel at the centre of screen Horizontal
let centreXBottomtLabel:NSLayoutConstraint = NSLayoutConstraint(item: bottomtLabel, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0);
//Setting height of 50pts to topLable
let heightTopLabel = NSLayoutConstraint.constraintsWithVisualFormat("V:[topLabel(50)]", options: [], metrics: nil, views: views)
//Setting width of 300pts to topLable
let widthTopLabel = NSLayoutConstraint.constraintsWithVisualFormat("H:[topLabel(300)]", options: [], metrics: nil, views: views)
//Setting height of 100pts to middleLabel
let heightMiddleLabel = NSLayoutConstraint.constraintsWithVisualFormat("V:[middleLabel(100)]", options: [], metrics: nil, views: views)
//Setting width of 150pts to middleLabel
let widthMiddleLabel = NSLayoutConstraint.constraintsWithVisualFormat("H:[middleLabel(150)]", options: [], metrics: nil, views: views)
//Setting height of 50pts to bottomtLabel
let heightBottomLabel = NSLayoutConstraint.constraintsWithVisualFormat("V:[bottomtLabel(50)]", options: [], metrics: nil, views: views)
//Setting width of 300pts to bottomtLabel
let widthBottomLabel = NSLayoutConstraint.constraintsWithVisualFormat("H:[bottomtLabel(300)]", options: [], metrics: nil, views: views)
/*This is important
Here you are setting the Y position of all lables
We are placing top label on top of middleLabel with standand spacing (8 pts) and bottom label below middle label with standard spacing.
*/
let labelYConstraint = NSLayoutConstraint.constraintsWithVisualFormat("V:[topLabel]-(spacingBetweenMiddleLabelAndTopLabel)-[middleLabel]-(spacingBetweenMiddleLabelAndBottomLabel)-[bottomtLabel]", options: [], metrics: metrics, views: views)
//If you want to set spacing or height and width with certain priority you can do that
let labelYConstraint = NSLayoutConstraint.constraintsWithVisualFormat("V:[topLabel]-(spacingBetweenMiddleLabelAndTopLabel#1000)-[middleLabel]-(spacingBetweenMiddleLabelAndBottomLabel#750)-[bottomtLabel]", options: [], metrics: metrics, views: views)
topLabel.addConstraints(heightTopLabel)
topLabel.addConstraints(widthTopLabel)
middleLabel.addConstraints(heightMiddleLabel)
middleLabel.addConstraints(widthMiddleLabel)
bottomtLabel.addConstraints(heightBottomLabel)
bottomtLabel.addConstraints(widthBottomLabel)
self.view.addConstraint(centreXMiddleLabel)
self.view.addConstraint(centreVMiddleLabel)
self.view.addConstraint(centreXTopLabel)
self.view.addConstraint(centreXBottomtLabel)
self.view.addConstraints(labelYConstraint)
Result after setting fixed points spacing between views:

The best solution would be to use auto layout but if you're going to stick with frames here's a bit of information.
Setting x and y in the frame will be overridden by changing the center point. If you'd like to achieve the positioning the best advice I could give in this situation would be something like. Untested but this might give you an idea.
Level = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 100))
Level.center = (self.view?.center)!
Level.textAlignment = NSTextAlignment.Center
GeschwindigkeitUILabel = UILabel(frame: CGRect(x: 0, y: Level.frame.origin.y+Level.frame.size.height + PADDING, width: 300, height: 50))
GeschwindigkeitUILabel.center = CGPointMake(self.view?.center.x, GeschwindigkeitUILabel.center.y)
Regel = UILabel(frame: CGRect(x: 0, y: GeschwindigkeitUILabel.frame.origin.y+GeschwindigkeitUILabel.frame.size.height+ PADDING, width: 300, height: 50))
Regel.center = CGPointMake(self.view?.center.x, Regel.center.y)

Related

Adding a UILabel to a subview is making the view it disappear

I am trying to create the following view heirarchy
Base UIView-> UIScrollView -> UIView -> UILabel
In the Storyboard I created the view->UIScrollView and made the Scrollview and the base view the same size and aligned their origins.
I am then adding the subsequent UIView -> UILabels in code.
In the ViewController viewDidLoad() function I am adding the UIView and the UILabel and also setting contraints on the UIScrollView.
I am having trouble adding the UILabel. If I just add the UIView to the scrollView its working fine (I gave them different colors just to see that).
As soon as I add the UILabel to the view I see the following issues --
the UIView seems to be disappearing and the label is getting added to the base View.
The UILabel is always getting added to the top corner of the screen. No matter what I do its not changing.
I have a feeling these two issues are connected and I am not adding the constraints on the label properly.
It will be great if someone can point out the error in my code.
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.orange
let boxViewOrigin = CGPoint(x:0, y:0)
let boxViewSize = CGSize(width: view.bounds.width * 3, height: view.bounds.height * 3)
let boxView = UIView(frame: CGRect(origin: boxViewOrigin, size: boxViewSize))
boxView.backgroundColor = UIColor.blue
boxView.translatesAutoresizingMaskIntoConstraints = false
let scrollView = view.subviews[0] as! UIScrollView
scrollView.addSubview(boxView)
// Add contraints
scrollView.contentSize = boxViewSize //CGSize(width: view.bounds.width * 3, height: view.bounds.height * 3)
scrollView.contentOffset = CGPoint(x: (view.bounds.origin.x + view.bounds.width) , y: (view.bounds.origin.y + view.bounds.height) )
/// ---- Commenting out everything from here to the end of the function makes the UIView appear properly. ------
let nameLabel = UILabel()
nameLabel.translatesAutoresizingMaskIntoConstraints = false
nameLabel.backgroundColor = UIColor.yellow
let nameLabelOrigin = CGPoint(x: boxView.bounds.midX, y: boxView.bounds.midY )
nameLabel.frame = CGRect(origin: nameLabelOrigin, size: CGSize(width: 30, height: 30) )
nameLabel.text = "BB"
//nameLabel.isEnabled = false
nameLabel.isUserInteractionEnabled = false
let verticalConstraint:NSLayoutConstraint = NSLayoutConstraint(item: nameLabel, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: boxView, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0)
let horizontalConstraint:NSLayoutConstraint = NSLayoutConstraint(item: nameLabel, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: boxView, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0)
boxView.addSubview(nameLabel)
view.addConstraints([verticalConstraint, horizontalConstraint])
}

Autoresize multiline UILabel in Swift

I have tried everything to auto-resize my UILabel in Swift. I can autoresize the text when it is one line but when it is two lines it no longer works. The text in the UILabel changes often happening about every 10 seconds. The code I have tried is:
let direction = UILabel(frame: CGRect(x: 95, y: 10, width: screenWidth - 95, height:100))
direction.numberOfLines = 0
direction.adjustsFontSizeToFitWidth = true
direction.lineBreakMode = .byWordWrapping
direction.textAlignment = .center
direction.minimumScaleFactor = 0.2
direction.font = UIFont.boldSystemFont(ofSize: 40)
view.addSubview(direction)
direction.text = "Ffafdafafdfa fafda dfafaf afa"
func updateDirection(update: String){
direction.text = update
}
The original text "Ffafdafafdfa fafda dfafaf afa" will automatically resize but when updateDirection is called the font size with not be changed from 40. I have also tried setting the number of lines to 2 and removing the .byWordWrapping. How can I get my UILabel to resize automatically?
Below code will keep the frame size and adjust the font size according with direction label content.
let backgroundView = UIView(frame: CGRect(x: 5, y: UINavigationController().navigationBar.frame.height + UIApplication.shared.statusBarFrame.height, width: UIScreen.main.bounds.width - 10, height: UIScreen.main.bounds.width - 100))
let direction = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
direction.backgroundColor = UIColor.green
direction.numberOfLines = 0
direction.textAlignment = .center
direction.font = UIFont.boldSystemFont(ofSize: 40)
direction.adjustsFontForContentSizeCategory = true
direction.adjustsFontSizeToFitWidth = true
direction.text = "This is some multiline label with a background colour" // Set or Initiate random function for your array here.
backgroundView.backgroundColor = UIColor.red
view.addSubview(backgroundView)
backgroundView.addSubview(direction)
Timer.scheduledTimer(timeInterval: 10.0, target: self, selector: #selector(random), userInfo: nil, repeats: true)
direction.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint(item: direction,
attribute: .leading,
relatedBy: .equal,
toItem: backgroundView,
attribute: .leadingMargin,
multiplier: 1.0,
constant: 0.0).isActive = true
NSLayoutConstraint(item: direction,
attribute: .trailing,
relatedBy: .equal,
toItem: backgroundView,
attribute: .trailingMargin,
multiplier: 1.0,
constant: 0.0).isActive = true
NSLayoutConstraint(item: direction,
attribute: .top,
relatedBy: .equal,
toItem: backgroundView,
attribute: .topMargin,
multiplier: 1.0,
constant: 0.0).isActive = true
NSLayoutConstraint(item: direction,
attribute: .bottom,
relatedBy: .equal,
toItem: backgroundView,
attribute: .bottomMargin,
multiplier: 1.0,
constant: 0.0).isActive = true
}
func random(sender: Timer) {
//Place your random func code here.
}
Output:
Try this without Constraints:
let direction = UILabel(frame: CGRect(x: 95, y: 10, width: 375 - 95, height:100))
direction.numberOfLines = 0
direction.adjustsFontSizeToFitWidth = true
direction.textAlignment = .center
direction.minimumScaleFactor = 0.2
direction.font = UIFont.boldSystemFont(ofSize: 40)
view.addSubview(direction)
direction.text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard"
I will try this code
It is use full
first create one function
func calchight(strin:String) -> CGFloat
{
let label = UILabel(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: CGFloat.greatestFiniteMagnitude))
label.numberOfLines = 0
label.text = strin
label.sizeToFit()
return label.frame.height + 2
}
then call this function in your right place, when you want to resize label
/--------------
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
let heit = self.calchight(strin: StringObject)
return (heit)
}
/--------------------------
this code is useful and not require Auto layout containers
UILabel will consider its content size to be one line of text, even when numberOfLines is set to a non-zero value, unless preferredMaxLayoutWidth is also set.
In other words, it can't predict how to wrap the text without preferredMaxLayoutWidth, so it doesn't plan to. It seems like during the autolayout process, a UILabel doesn't know how to balance the priority between its width set by layout constraints outside of it and the wrapping of text.
So it doesn't exert any additional pressure (more than the height of one line) on the vertical dimension even when its Content Compression Resistance is higher than other views', because it will assume that by exerting pressure in the horizontal axis, its content will be displayed.
So the solution is to set preferredMaxLayoutWidth, so that it is able to determine the height of the content after wrapping the text and then it uses that content size to negotiate layout with other views.
You probably want to avoid hard-coding the width of your UILabel. Assuming that its container's width is not going to change based on autolayout, it should be safe to use that. In this case I'm in a UITableViewCell or UICollectionViewCell and the "title label" spans the full width of the cell.
override func layoutSubviews() {
// Tell the label it should wrap text at the same width as this cell's contentView.
titleLabel.preferredMaxLayoutWidth = contentView.frame.width
super.layoutSubviews()
}
Try using function sizetofit() after assigning text to your label.
like:
direction.sizeToFit()

Fixed Height Constraints for UIStackview's subviews

I have a UIScrollView that has a UIStackView subview, call it stack. I want to have a dynamic number of subviews in stack, but these subviews will have different heights. How can I achieve this? Please note that I'm trying to shy away from Storyboard..
let scrollView = UIScrollView(frame: CGRect(x: 20, y: 20, width: view.frame.width - 20, height: view.frame.height - 20))
scrollView.center = view.center
self.view.addSubview(scrollView)
let stack = UIStackView(frame: CGRect(x: 20, y: 20, width: scrollView.frame.width - 40, height: scrollView.frame.height - 40))
stack.axis = .vertical
stack.alignment = .fill
stack.distribution = .fillProportionally
stack.spacing = 20
scrollView.addSubview(stack)
let label1 = UILabel()
label1.text = "This is going to be very, very long. I don't know how to make this guy longer. Words and words and more words. // Do any additional setup after loading the view, typically from a nib."
label1.numberOfLines = 0
label1.sizeToFit()
// Add more labels similar to label1
I tried adding a constraint to each of my UILabel subview, but it doesn't really work..
let x = NSLayoutConstraint(item: label1, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: label1.frame.size.height)
label1.addConstraint(x)
Please help! Thanks.
Try changing the stack view's distribution mode :
stack.distribution = .fillProportionally
(I'm not sure if that's the correct one, if it's not just try all the different distribution modes :) )

How to programmatically add an InputAccessoryView with Autolayout?

I am trying to add a UIView with "Done" button as an input accessory view to the text field.
let view = UIView()
let doneButton = UIButton(type: .Custom)
doneButton.setTitle("Done", forState: .Normal)
doneButton.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(doneButton)
view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[button]-|", options: NSLayoutFormatOptions.DirectionLeadingToTrailing, metrics: nil, views: ["button":doneButton]))
view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[button]|", options: NSLayoutFormatOptions.DirectionLeadingToTrailing, metrics: nil, views: ["button":doneButton]))
view.addConstraint(NSLayoutConstraint(item: view, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: doneButton, attribute: NSLayoutAttribute.Height, multiplier: 1, constant: 0)) // Even this does not work
self.emailTextField.inputAccessoryView = view
But however I cannot see the views height being set nor the buttons in the View Hierarchy debugger/inspector in Xcode.
But if I add a view by setting its frame I can see the view being added.
Also I tried setting height constraint forcibly to a constant 21 and it broke some other constraints which I had not added _UIKBAutolayoutHeightConstraint
"<NSLayoutConstraint:0x7fa3c962be50 UIView:0x7fa3c963bf60.height == UIButton:0x7fa3c963c0d0.height + 21>",
"<NSLayoutConstraint:0x7fa3c95e0a90 '_UIKBAutolayoutHeightConstraint' V:[UIView:0x7fa3c963bf60(0)]>"
Any one faced this issue before ?
Swift 3+
You need to specify size of toolbar view in first line.
Don't use 'view' as variable in viewcontroller class since it creates confusion vs self.view
override func viewDidLoad() {
super.viewDidLoad()
let toolBar = UIView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: 50))
toolBar.backgroundColor = .gray
let doneButton = UIButton(type: .custom)
doneButton.setTitle("Done", for: .normal)
doneButton.translatesAutoresizingMaskIntoConstraints = false
toolBar.addSubview(doneButton)
toolBar.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:[button]-|",
options: .directionLeadingToTrailing,
metrics: nil,
views: ["button":doneButton]))
toolBar.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[button]|",
options: .directionLeadingToTrailing,
metrics: nil,
views: ["button":doneButton]))
self.emailTextField.inputAccessoryView = toolBar
}

Swift : How to make a Black screen to guidelines for user to use app

Im using swift 1.2.
I need to create a guideline for user to use my app.
it look like: a black transparent screen, 1 button highlight with note how to use, what is it.
i have searching for solution but still get stuck.
Can anybody help me?
Thanks!
If I understood correctly what you want, it can be done something like this*:
class TutorialView : UIView
{
override init(frame: CGRect)
{
super.init(frame: frame)
self.backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.5)
}
convenience init()
{
self.init(frame: CGRectZero)
}
required init?(coder aDecoder: NSCoder)
{
fatalError("init(coder:) has not been implemented")
}
func showFromWindow()
{
let window = UIApplication.sharedApplication().keyWindow!
self.translatesAutoresizingMaskIntoConstraints = false
window.addSubview(self)
window.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[tutorialView]-0-|", options: NSLayoutFormatOptions.DirectionLeftToRight, metrics: nil, views: ["tutorialView": self]))
window.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[tutorialView]-0-|", options: NSLayoutFormatOptions.DirectionLeftToRight, metrics: nil, views: ["tutorialView": self]))
}
func addCommentToTopRightItem(comment: String, afterDelay: NSTimeInterval)
{
let topMargin : Int32 = 54
let rightMargin : Int32 = 24
let height : Int32 = 100
// we need two views - one for arrow and second for text
let commentLabel = UILabel()
let arrowView = UIView()
commentLabel.translatesAutoresizingMaskIntoConstraints = false
arrowView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(commentLabel)
self.addSubview(arrowView)
// setup layout for views
// |^^^^^|
// |^^^^^|arrow|
// |label|_____|
// |_____|
//
// we place center of Y label to the bottom of arrow view
// to an arrow coming out of the middle of text
let metrics = ["topmargin" : NSNumber(int: topMargin), "rightmargin": NSNumber(int: rightMargin),"height" : NSNumber(int: height)]
let views = ["label": commentLabel, "arrow": arrowView]
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-topmargin-[arrow(==height)]", options: NSLayoutFormatOptions.DirectionLeftToRight, metrics: metrics, views: views))
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[label(==height)]", options: NSLayoutFormatOptions.DirectionLeftToRight, metrics: metrics, views: views))
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-rightmargin-[arrow(==height)]-[label]-0-|", options: NSLayoutFormatOptions.DirectionRightToLeft, metrics: metrics, views: views))
self.addConstraint(NSLayoutConstraint(item: commentLabel, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: arrowView, attribute: NSLayoutAttribute.Bottom, multiplier: 1.0, constant: 1.0))
// configure text label
commentLabel.textColor = UIColor.whiteColor()
commentLabel.numberOfLines = 0
commentLabel.textAlignment = NSTextAlignment.Right
commentLabel.font = UIFont(name: "HelveticaNeue-Light", size: 16)
commentLabel.text = comment
// configure arrow view
self.layoutIfNeeded()
let d : CGFloat = min(arrowView.frame.size.height, arrowView.frame.size.width)
// draw arc line from {0, 1} to {1, 0}
// | /|
// |/_|
let linePath = UIBezierPath()
linePath.moveToPoint(CGPointMake(0, d))
linePath.addCurveToPoint(CGPointMake(d, 0), controlPoint1: CGPointMake(d*0.5, d), controlPoint2: CGPointMake(d, d*0.5))
let lineLayer = CAShapeLayer()
lineLayer.path = linePath.CGPath
lineLayer.strokeColor = UIColor.redColor().CGColor
lineLayer.backgroundColor = UIColor.clearColor().CGColor
lineLayer.fillColor = UIColor.clearColor().CGColor
lineLayer.lineWidth = 2
// draw triangle near {1, 0} point
let trianglePath = UIBezierPath()
trianglePath.moveToPoint(CGPointMake(d, 0))
trianglePath.addLineToPoint(CGPointMake(d - 5, 15))
trianglePath.addLineToPoint(CGPointMake(d + 5, 15))
trianglePath.closePath()
let triangleLayer = CAShapeLayer()
triangleLayer.path = trianglePath.CGPath
triangleLayer.strokeColor = UIColor.redColor().CGColor
triangleLayer.backgroundColor = UIColor.clearColor().CGColor
triangleLayer.fillColor = UIColor.redColor().CGColor
triangleLayer.lineWidth = 2
// line + triangle = arrow :)
arrowView.layer.addSublayer(lineLayer)
arrowView.layer.addSublayer(triangleLayer)
arrowView.alpha = 0.0
commentLabel.alpha = 0.0
UIView.animateWithDuration(0.8, delay: afterDelay, options: UIViewAnimationOptions.AllowAnimatedContent, animations:
{ () -> Void in
arrowView.alpha = 1.0
commentLabel.alpha = 1.0
}, completion: nil)
}
func addButton(title: String, highlighteAfterDelay: NSTimeInterval)
{
// same as before
let button = UIButton()
button.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(button)
self.addConstraint(NSLayoutConstraint(item: button, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.CenterX, multiplier: 1.0, constant: 1.0))
self.addConstraint(NSLayoutConstraint(item: button, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.Bottom, multiplier: 1.0, constant: -20.0))
self.addConstraint(NSLayoutConstraint(item: button, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1.0, constant: 120.0))
self.addConstraint(NSLayoutConstraint(item: button, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1.0, constant: 40.0))
button.setTitle(title, forState: UIControlState.Normal)
button.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Normal)
button.layer.cornerRadius = 20.0
button.layer.masksToBounds = false
button.layer.borderWidth = 1.0
button.layer.borderColor = UIColor.whiteColor().CGColor
button.layer.shadowColor = UIColor.whiteColor().CGColor
button.layer.shadowOpacity = 0.4
button.layer.shadowRadius = 4
button.layer.shadowOffset = CGSizeMake(0, 0)
button.alpha = 0.2
button.enabled = false
UIView.animateWithDuration(0.8, delay: highlighteAfterDelay, options: UIViewAnimationOptions.AllowAnimatedContent, animations:
{ () -> Void in
button.alpha = 1.0
button.enabled = true
}, completion: nil)
}
}
In some view controller:
let tutorial = TutorialView()
tutorial.showFromWindow()
tutorial.addCommentToTopRightItem("Tap this button to do something amazing action!", afterDelay: 1.0)
tutorial.addButton("Done", highlighteAfterDelay: 3.0)
Result:
*I don't have a compiler version 1.2 but I think that there should be no serious differences.
I see the problem now, you can add UView on top of it, give it a color with alpha, and get frame by using
convertRect(button.frame, toView:overlayView)
Hopefuly helps

Resources