Getting the View's center when initialing a variable - swift

I'm very new to Swift and trying to make a simple application to learn.
I'm trying to setup on screen a UISlider and set it in the middle of the screen, the problem is that the view is probably isn't ready yet.
I tried to do something like this:
> private let bullsEyeSlider: UISlider = {
> let slider = UISlider(frame: CGRect(x: self.view.frame.midX,y:100, width: 500, height: 20))
> slider.minimumValue = 0
> slider.maximumValue = 100
> return slider
> }()
to get the center of the view (the x center at least) but of course it can't work.
I'm trying to think of something else to do but other than just setting up the slider after the view is initialised I can't think of anything else.
Tried to search the web but with no luck.

In viewDidLayoutSubviews method of the view controller add:
bullsEyeSlider.center = view.center

Related

Swift method that is called after autolayout is finalized

I have a method that draws pins by adding an ImageView on top of a slider when a button is pressed. Here is the code:
var loopStartImageView : UIImageView = UIImageView()
func addLoopDrawing(at time: CMTime, for loop: Int) {
let imgHeight : CGFloat = 30
let imgWidth: CGFloat = 30
var pinImg : UIImage = UIImage(named: "pin2x")!
let inset = slider.frame.origin.x
let width = slider.bounds.width
let xPos : CGFloat = CGFloat((Float(time.seconds) / slider.maximumValue)) * width + inset - (imgWidth / 2)
var yPos : CGFloat = slider.frame.origin.y - (slider.frame.height / 2) - 3
let imgV = UIImageView(frame: CGRect(x: xPos, y: yPos, width: imgWidth, height: imgHeight))
imgV.image = pinImg
loopStartImageView = imgV
view.addSubview(loopStartImageView)
view.sendSubviewToBack(loopStartImageView)
}
The drawing is correct when I don't use autolayout to set the position of the slider, but once I do it shows up below the actual positioning.
This method is called in viewDidLoad. My guess is that for some reason the auto layout positioning is not set when viewDidLoad is called.
I was wondering if there is a method that is called once auto layout is fully adjusted?
//
This is what it should look like:
But this is how the view loads (even when calling the addLoopDrawing function inside the viewDidLayoutSubviews)
I was wondering if there is a method that is called once auto layout is fully adjusted?
That would be viewDidLayoutSubviews. That is a very good time to do things that depend upon things having their correct frame, but beware: it can be called many times. The usual thing, therefore, is to implement it along with a Bool property to check that this is the first time.
On the other hand, it might be better not to ask an x-y question like this. The idea of an image view on top of a slider seems wrong. It might be better to describe what you are really trying to do.

How to insert Custom Label with text into View with Animation?

Im making a small boxing app. This whole week iv been trying to work out how to solve my current problem above, with no luck :(.
Summary
Basically Its a 1 v 1 game. Each time the user hits the other player I want to make a tiny number pop up near him and float up and dissappear.
Its sort of like when you play MMORPG's and when you do dmg you see how much you did. See image below for an example!
So basically everytime the user hits the other player I want a little number to pop up on the screen to show the dmg and then float up and disappear.
Details
I am building the game on a simple UIView
The label is a UILabel
Anywhere How I can achieve this?
Thank you!
Create a label, then use UIView.animateWithDuration to animate it.
let label = UILabel(frame: CGRect(origin: point/*The point where you want to add your label*/, size: CGSize(width: 50, height: 50)))
label.text = "+1"
label.font = UIFont()//Your font
label.textColor = UIColor.blueColor()
label.alpha = 1
self.view.addSubview(label)
UIView.animateWithDuration(1) {
label.center = CGPoint()//The point where you want your label to end up
label.alpha = 0
}
Edit: As mentioned in the comments, you asked for how to create the label at a random point. Try this:
let screenWidth = self.view.frame.width
let screenHeight = self.view.frame.height
let randomX = CGFloat(arc4random_uniform(UInt32(screenWidth)))
let randomY = CGFloat(arc4random_uniform(UInt32(screenHeight)))
let point = CGPoint(x: randomX, y: randomY)
As you will notice, for the width and height, I use the view's frame's width and height. You may want to use the view's bounds. For more on this, check out this SO Post.

UIScrollView in tvOS

I have a view hierarchy similar to the one in the image below (blue is the visible part of the scene):
So I have a UIScrollView with a lot of elements, out of which I am only showing the two button since they are relevant to the question. The first button is visible when the app is run, whereas the other one is positioned outside of the initially visible area. The first button is also the preferredFocusedView.
Now I am changing focus between the two buttons using a UIFocusGuide, and this works (checked it in didUpdateFocusInContext:). However, my scroll view does not scroll down when Button2 gets focused.
The scroll view is pinned to superview and I give it an appropriate content size in viewDidLoad of my view controller.
Any ideas how to get the scroll view to scroll?
Take a look at UIScrollView.panGestureRecognizer.allowedTouchTypes. It is an array of NSNumber with values based on UITouchType or UITouch.TouchType (depending on language version). By default allowedTouchTypes contains 2 values - direct and stylus. It means that your UIScrollView instance will not response to signals from remote control. Add the following line to fix it:
Swift 4
self.scrollView.panGestureRecognizer.allowedTouchTypes = [NSNumber(value: UITouchType.indirect.rawValue)]
Swift 4.2 & 5
self.scrollView.panGestureRecognizer.allowedTouchTypes = [NSNumber(value: UITouch.TouchType.indirect.rawValue)]
Also, don't forget to set a correct contentSize for UIScrollView:
self.scrollView.contentSize = CGSize(width: 1920.0, height: 2000.0)
Finally I solved this by setting scrollView.contentSize to the appropriate size in viewDidLoad.
You need to add pan gesture recognizer. I learned from here: http://www.theappguruz.com/blog/gesture-recognizer-using-swift. I added more code to make it not scrolling strangely, e.g. in horizontal direction.
var currentY : CGFloat = 0 //this saves current Y position
func initializeGestureRecognizer()
{
//For PanGesture Recoginzation
let panGesture: UIPanGestureRecognizer = UIPanGestureRecognizer(target: self, action: Selector("recognizePanGesture:"))
self.scrollView.addGestureRecognizer(panGesture)
}
func recognizePanGesture(sender: UIPanGestureRecognizer)
{
let translate = sender.translationInView(self.view)
var newY = sender.view!.center.y + translate.y
if(newY >= self.view.frame.height - 20) {
newY = sender.view!.center.y //make it not scrolling downwards at the very beginning
}
else if( newY <= 0){
newY = currentY //make it scrolling not too much upwards
}
sender.view!.center = CGPoint(x:sender.view!.center.x,
y:newY)
currentY = newY
sender.setTranslation(CGPointZero, inView: self.view)
}

Layering transparent images and text on top of a mapView (Swift)

I want to put a transparent box on top of a mapView and then some text on top of that.
I can do this treating the image as a button and altering the alpha setting but only the last UILabel I put in place remains black, the rest are muted.
Is this possible with Tags or something or does it have to be done programatically?
Anyway after a couple of hours sleuthing this is a working solution.
Declare your layer
#IBOutlet weak var layerView: UIView!
var myLayer: CALayer {
return layerView.layer
}
Put a UIView on your ViewController and link it to layerView.
Create a method/func to display the frame, e.g.
func displayMyFrame() {
myLayer.frame = CGRectMake(100, 100, 200, 40)
myLayer.backgroundColor = UIColor.whiteColor().CGColor
myLayer.borderWidth = 1.0
myLayer.borderColor = UIColor.redColor().CGColor
myLayer.shadowOpacity = 0.6
myLayer.cornerRadius = 5.0
myLayer.shadowRadius = 10.0
myLayer.opacity = 0.6
}
Put your UILabels on the view and change their tags to 1 (in this example).
Call the func in viewDidLoad.
displayMyFrame()
view.layer.insertSublayer(myLayer, atIndex: 1)
The atIndex: 1 means that this frame will be put behind the UILabels with a Tag of 1.
This works, hope that it helps.

Swift get Y coordinate of current element

I got some UILabel which can be pressed to open a menu. When pressed, they call my function with the label itself as a parameter. I make a popover that behave correctly in phone view but I would like to position it when it is on ipad view.
My problem is that I can not get the exact position of the UILabel that was pressed.
I tried
myYCoordinates = label.bounds.origin.y
or
myYCoordinates = label.frame.origin.y
to
optionMenu.popoverPresentationController?.sourceRect = CGRectMake(self.view.bounds.size.width / 2, myYCoordinates, 1.0, 1.0)
But I cant get the good coordinate.
I don't know if it is because my label are in a tableview with 2 section or if there is a way at all.
Thank in advance for the help.
Here is my sceen (cropped du to development confidentiality)
Here is what append when I press my label
And here is what I would like ti to look like
I tried
optionMenu.popoverPresentationController?.sourceRect = label.frame
Based on #Özgür Erzil answer, I found out that I could simply use
optionMenu.popoverPresentationController?.sourceView = label
optionMenu.popoverPresentationController?.sourceRect = CGRectMake(label.frame.width, label.frame.height / 2, 1.0, 1.0)
By setting the source view to my label and using the label width and height to position it.
Thank
if you create your UILabel dynamically, try to set the position when you set it like:
CGRectMake(x, y, width, height)
var label = UILabel(frame: CGRectMake(0, 0, 200, 20))
or if it is in storyBoard, you have to use constraint methods and use autolayout. Explained here