In Swift, I have a view with three objects. I want the button and label to be on top of the image. This is a concept like maybe layers in Photoshop. Currently, the image is on top of the button and label, so you can not see the button and label. How is this done?
My code is here:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let myFirstLabel = UILabel()
let myFirstButton = UIButton()
let myFirstImage = UIImage(named: "1792614.jpg")
let myFirstImageView = UIImageView(image: myFirstImage)
myFirstLabel.text = "I made a label on the screen #toogood4you"
myFirstLabel.font = UIFont(name: "MarkerFelt-Thin", size: 45)
myFirstLabel.textColor = UIColor.redColor()
myFirstLabel.textAlignment = .Center
myFirstLabel.numberOfLines = 5
myFirstLabel.frame = CGRectMake(15, 54, 300, 500)
myFirstButton.setTitle("✸", forState: .Normal)
myFirstButton.setTitleColor(UIColor.blueColor(), forState: .Normal)
myFirstButton.frame = CGRectMake(160, 284, 50, 50)
myFirstButton.addTarget(self, action: "pressed:", forControlEvents: .TouchUpInside)
self.view.addSubview(myFirstLabel)
self.view.addSubview(myFirstButton)
self.view.addSubview(myFirstImageView)
}
func pressed(sender: UIButton!) {
var alertView = UIAlertView()
alertView.addButtonWithTitle("Ok")
alertView.title = "title"
alertView.message = "message"
alertView.show()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
The answer is here:
self.view.addSubview(myFirstLabel)
self.view.addSubview(myFirstButton)
self.view.addSubview(myFirstImageView)
When you add a subview, it always gets put at the top, to achieve what you want, add the view you want at the bottom first, and the one you want on top last:
self.view.addSubview(myFirstImageView)
self.view.addSubview(myFirstButton)
self.view.addSubview(myFirstLabel)
You're adding the views in this order:
self.view.addSubview(myFirstLabel)
self.view.addSubview(myFirstButton)
self.view.addSubview(myFirstImageView)
which means myFirstImageView is going to be on top. Reversing the order of the addSubview calls will do what you want.
Related
I have an app that has multiple views and one of them is a SceneView as you can see below. The SceneView is not the initial view. Users can open the SceneView by triggering a segue from another ViewController but when I want to add a nav bar to the SceneView, an error has occured.
So how can I add a navigation bar or a button to a sceneView? If there is no way, how can I manage to dismiss segue from the SceneView?
I couldn't find a way to add a navigationBar on top of a sceneView but I figured out how to add a button to a sceneView. If we create a button programmatically and add that button to the sceneView, we can navigate via that button.
Here's what we can do;
import UIKit
import SceneKit
class ViewController: UIViewController {
var scnView: SCNView?
var exampleScn = SCNScene(named: "ExampleScn")
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
self.scnView = SCNView(frame: self.view.frame)
self.scnView?.scene = exampleScn
self.view.addSubview(self.scnView!)
let button = UIButton(type: .system)
button.tintColor = UIColor.black
button.titleLabel?.font = UIFont(name: "Arial", size: 25)
button.setTitle("Back", for: .normal)
button.sizeToFit()
button.addTarget(self, action: #selector(didPressBack), for: .touchUpInside)
button.center.x = 50
button.frame.origin.y = 20
scnView.addSubview(button)
}
#objc func didPressBack (sender: UIButton!) {
dismiss(animated: true, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
if we do this, the result will look like this:
In my swift project I have a button and I want to print on a label how much time this button has been pressed.
How can I resolve this problem?
Adding to DHEERAJ's answer, you just need to add following code in func pressed(sender: UIButton!) to achieve what you need:
let date = NSDate()
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = .MediumStyle
let dateString = dateFormatter.stringFromDate(date)
yourLabelName.text = dateString
Hope this might help.
To show how many times the button has been clicked you could class variable.
class SampleViewController: UIViewController {
var counter : Int!
#IBOutlet weak var yourLabelName: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
counter = 1
let myFirstButton = UIButton(frame: CGRectMake(10, 50, 320, 40))
myFirstButton.setTitle("Tap Me", forState: .Normal)
myFirstButton.setTitleColor(UIColor.blueColor(), forState: .Normal)
myFirstButton.addTarget(self, action: "pressed:",forControlEvents: .TouchUpInside)
self.view.addSubview(myFirstButton)
}
func pressed(sender: UIButton!)
{
yourLabelName.text = "Pressed : \(counter)"
counter = counter + 1
}
}
Here is how button is created programmatically and prints a text in label when button is pressed.
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let myFirstButton = UIButton()
myFirstButton.setTitle("Tap Me", forState: .Normal)
myFirstButton.setTitleColor(UIColor.blueColor(), forState: .Normal)
myFirstButton.frame = CGRectMake(10, 50, 320, 40)
myFirstButton.addTarget(self, action: "pressed:", forControlEvents: .TouchUpInside)
self.view.addSubview(myFirstButton)
}
func pressed(sender: UIButton!)
{
yourLabelName.text=#"Your Text is here"
}
var ExitImg: UIImage!
var ExitButton: UIButton!
func missileHitAction(sender:UIButton!)
{
self.view.viewWithTag(12221)?.removeFromSuperview()
ExitImg = nil
ExitButton = nil
}
override func viewDidLoad() {
super.viewDidLoad()
ExitImg = UIImage(contentsOfFile: "/Users/Joca/Desktop/Game_dev/missile_gun1")
ExitButton = UIButton.buttonWithType(UIButtonType.System) as UIButton
ExitButton.frame = CGRectMake(5, 285, 70, 30)
ExitButton.imageView?.tag = 12221
ExitButton.setBackgroundImage(ExitImg, forState: UIControlState.Normal)
ExitButton.addTarget(self, action: "missileHitAction:", forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(ExitButton)
}
This is a sample test project for deallocating buttons, on button press button should be deallocated, but its not :(
You are creating a button, but are not setting its tag. Instead, you are setting its image view's tag. Instead of:
ExitButton.imageView?.tag = 12221
I think you intended:
ExitButton.tag = 12221
I'm currently tying to familiarise myself with UIKit under Swift and work out the best way of adding UI elements programmatically. However I'm finding that a touch can end way outside the button in which it began yet still register as a TouchUpInside event. The ViewController below is from a single view application and it is straightforward to start a touch on, say, button 17, end it on button 18 and still have buttonAction() declare "Button tapped: 17".
Any idea what I'm missing here?
(Edit: This is under Xcode 6 beta 3 BTW.)
// ViewController.swift
import UIKit
class ViewController: UIViewController {
let scrollView:UIScrollView = UIScrollView()
var GWIDTH:Float = 0.0
var GHEIGHT:Float = 0.0
override func viewDidLoad() {
super.viewDidLoad()
GWIDTH = self.view.bounds.size.width
GHEIGHT = self.view.bounds.size.height
scrollView.frame = CGRectMake(10, 10, GWIDTH-10, GHEIGHT-20)
scrollView.contentSize = CGSize(width:GWIDTH-20, height: 0)
self.view.addSubview(scrollView)
for currentTag in 1...30{
var currentButton = UIButton.buttonWithType(UIButtonType.System) as UIButton
currentButton.frame = CGRectMake(100, scrollView.contentSize.height, 100, 50)
currentButton.backgroundColor = UIColor.greenColor()
currentButton.setTitle("Test Button \(currentTag)", forState: UIControlState.Normal)
currentButton.tag = currentTag
currentButton.addTarget(self, action: "buttonAction:", forControlEvents: UIControlEvents.TouchUpInside)
scrollView.addSubview(currentButton)
scrollView.contentSize = CGSize(width:GWIDTH-20,height:2.0+currentButton.frame.size.height+currentButton.frame.origin.y)
}//next
}// end viewDidLoad()
func buttonAction(sender:UIButton!){
println("Button tapped: \(sender.tag)")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func prefersStatusBarHidden() -> Bool {
return true
}
}
Okay it's taken a fair bit of digging to get to the bottom of this but a couple of helpful Obj-C links...
UIControlEventTouchDragExit triggers when 100 pixels away from UIButton
How to correctly subclass UIControl?
http://www.bytearray.org/?p=5336 (particularly line 89)
...and it seems that the behaviour is standard due to the touch interface (personally I instinctively find the default zone excessive but I'm sure Apple did its homework) and can be overridden by either sub-classing UIControl or interrogating the position of the control event.
I've opted for the latter and here's an implementation specifically in Swift:
// ViewController.swift
import UIKit
class ViewController: UIViewController {
let buttonCount = 3
override func viewDidLoad() {
super.viewDidLoad()
for currentTag:Int in 1...buttonCount{
var currentButton = UIButton.buttonWithType(UIButtonType.System) as UIButton
currentButton.frame = CGRectMake(50, Float(currentTag*50), 120, 50)
currentButton.backgroundColor = UIColor.greenColor()
currentButton.setTitle("Test Button \(currentTag)", forState: UIControlState.Normal)
currentButton.contentEdgeInsets = UIEdgeInsets(top:3,left:6,bottom:3,right:6)
currentButton.tag = currentTag
currentButton.addTarget(self,
action: "btn_TouchDown:",
forControlEvents: UIControlEvents.TouchDown)
currentButton.addTarget(self,
action: "btn_TouchDragExit:",
forControlEvents: UIControlEvents.TouchDragExit)
currentButton.addTarget(self,
action: "btn_TouchUpInside:event:",
forControlEvents: UIControlEvents.TouchUpInside)
currentButton.sizeToFit()
self.view.addSubview(currentButton)
}//next
}// end viewDidLoad()
func btn_TouchDown(sender:UIButton!){
println("TouchDown event: \(sender.tag)\n")
}
func btn_TouchDragExit(sender:UIButton!){
println("TouchDragExit event: \(sender.tag)\n")
}
func btn_TouchUpInside(sender:UIButton!,event:UIEvent!){
println("TouchUpInside event: \(sender.tag)")
var currentTouch:CGPoint = event.allTouches().anyObject().locationInView(sender)
println( "Point: \(currentTouch.x), \(currentTouch.y)\n" )
if currentTouch.x > sender.frame.width{return}
if currentTouch.x < 0 {return}
if currentTouch.y > sender.frame.height{return}
if currentTouch.y < 0 {return}
println("Event ended within frame!")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func prefersStatusBarHidden() -> Bool {
return true
}
}
I have a UIButton. I want it to generate at random places on the screen. It returns no errors, and runs, but nothing shows up on the screen. I tried hard-coding the values, and that works. I am using Swift.
CODE:
import UIKit
class ViewController: UIViewController {
let changingPoint = UIButton()
let dot = UIImage(named: "sponsor-dot.png")
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
changingPoint.setImage(dot, forState: .Normal)
changingPoint.addTarget(self, action: "pointPressed:", forControlEvents: .TouchUpInside)
changingPoint.frame = CGRectMake(CGFloat(arc4random()%(320)), CGFloat(arc4random()%(568)), 150, 150)
self.view.addSubview(changingPoint)
}
func pointPressed(sender: UIButton!) {
changingPoint.frame = CGRectMake(CGFloat(arc4random()%(320)), CGFloat(arc4random()%(568)), 150, 150)
println()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I Believe that you not set a background color for the button.
changingPoint.backgroundColor = UIColor.blackColor() //or any other color that you want
I don't think your image is loading properly. Try printing dot to see if it is null:
println("image: \(dot)")