Changing frame of button with arc4random? - ios

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)")

Related

array.insert won't save elements

I'm a beginner in Swift and creating the Tictactoe game as a part of practices. I'm trying to create an empty array with 9 elements in order to track the results of the game. I'm using .insert method to fill up corresponding elements. However the array won't save the previous elements and keep updating its self from initial array every time a player taps a button. (Oh gosh I'm really bad at explaining stuff in writing)
Here is my code:
import UIKit
class ViewController: UIViewController {
var cross = false
#IBAction func buttonPressed(_ sender: UIButton) {
var resultArray = [String!](repeating: nil, count:9)
let button = sender
var index = button.tag
if cross{
button.setImage(UIImage(named: "cross.png"), for: UIControlState.normal)
resultArray.insert("cross", at: index)
resultArray.remove(at: index+1)
cross = false
}
else{
button.setImage(UIImage(named: "nought.png"), for: UIControlState.normal)
resultArray.insert("nought", at: index)
resultArray.remove(at: index+1)
cross = true
}
print(resultArray)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
And here is what I get when running the code
You are resetting your array on each button press, move
var resultArray = [String!](repeating: nil, count:9)
out of the function so that it is defined at the class level so it wont be reset each time.

Calculate button height of keyboard buttons

I'm working on a universal keyboard extension. Currently I want to calculate the height of a single button. The keyboard has 4 rows as the normal iOS keyboard. Because the space between the buttons (y distance) is 5 I calculated: (self.view.frame.height-(5*5))/4 5x5 because the distance to the top and the bottom is included. Now, if I run the app, one button isn't around 1/4 of the screen. Instead the button's height is around 2/3 of the keyboard view. I really can't find my mistake. I hope you can help me with this calculation.
My current code:
import UIKit
class KeyboardViewController: UIInputViewController, UIScrollViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidLayoutSubviews() {
print((self.view.frame.height-25)/4)
addButtons()
}
func addButtons() {
let buttonHeigth = (self.view.frame.height-25)/4
let button = ResizableButton()
button.frame = CGRect(x: CGFloat(5), y: CGFloat(10), width: CGFloat(button.frame.size.width), height: CGFloat(buttonHeigth))
button.addTarget(self, action: #selector(keyPressed(sender:)), for: .touchUpInside)
button.layer.cornerRadius = 10
button.layer.masksToBounds = false
self.scrollView.addSubview(button)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated
}
override func textWillChange(_ textInput: UITextInput?) {
// The app is about to change the document's contents. Perform any preparation here.
}
override func textDidChange(_ textInput: UITextInput?) {
// The app has just changed the document's contents, the document context has been updated.
var textColor: UIColor
let proxy = self.textDocumentProxy
if proxy.keyboardAppearance == UIKeyboardAppearance.dark {
textColor = UIColor.white
} else {
textColor = UIColor.black
}
self.nextKeyboardButton.setTitleColor(textColor, for: [])
}
}

Default Back Button Text and Font Setting

By default, Navigation back button text comes as previous screen title or <
I am trying to change that to just <=|
But Its coming as shown in the picture
BackButton Image.
So, I want to know how to change its font to make big <=| and remove the default <
I tried
Tried the same code in viewDidLoad of first start screen,
So i also want to know where to place this code:
override func viewWillAppear(animated: Bool)
{
self.navigationItem.leftBarButtonItem?.title = "<=|"
let FntStgVal = [NSFontAttributeName:UIFont.systemFontOfSize(50, weight: UIFontWeightLight)]
self.navigationItem.leftBarButtonItem?.setTitleTextAttributes(FntStgVal, forState: .Normal)
}
Change your code in viewDidLoad like this.
class BaseViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
func setNavigationWithCustomBackButton() {
let btnLeft:UIButton! = UIButton(frame: CGRectMake(0, 0, 20, 16))
btnLeft.setTitle("<=|", forState: .Normal)
btnLeft.titleLabel?.font = UIFont.systemFontOfSize(19, weight: UIFontWeightLight)
btnLeft!.addTarget(self, action: "handleBack:",forControlEvents: UIControlEvents.TouchUpInside)
let leftItem:UIBarButtonItem = UIBarButtonItem(customView: btnLeft!)
self.navigationItem.leftBarButtonItem = leftItem
}
func handleBack(sender: UIButton) {
self.navigationController?.popViewControllerAnimated(true)
}
}
Now use this BaseViewController as parent of your all viewController and call its method in viewDidLoad like this.
class ViewController1: BaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.setNavigationWithCustomBackButton()
}
}
Now it will add custom back button in your NavigationBar.
Hope this will help you.

TouchUpInside boundaries outside of UIButton

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
}
}

In swift, how do I make layers of a view programmatically?

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.

Resources