swift UIview removeFormSuperview - swift

this is a test code,I want to add uiview to storyBoard ,and wait 1 second, and remove it .but the uiview doesn't appear , the code is down
var uiview1 = UIView()
uiview1.frame = CGRectMake(0, 0, 50, 50)
uiview1.backgroundColor = UIColor.blackColor()
self.view.addSubview(uiview1)
sleep(1)
uiview1.removeFromSuperview()

sleep() is not a good idea in this way. It will become totally unresponsive and block. Use NSTimer.scheduledTimerWithTimeInterval instead.
class ViewController: UIViewController {
var uiview1 = UIView()
override func viewDidLoad() {
super.viewDidLoad()
uiview1.frame = CGRectMake(0, 0, 50, 50)
uiview1.backgroundColor = UIColor.blackColor()
self.view.addSubview(uiview1)
var timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("dismissView"), userInfo: nil, repeats: false)
}
func dismissView() {
uiview1.removeFromSuperview()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}

Related

Defining a #selector method when it can't access a programmatically created UILabel

If you define a UILabel programmatically, it must be done so in viewDidLoad()? But, if you were to define a #selector method that needed to set said label, it would be impossible given that the #objc selector method needs to be outside the scope of the viewDidLoad() method, where it cannot access the label. How do you get around this?
class ViewController: UIViewController {
var count = 4
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 150))
label.center = CGPoint(x: 250, y: 430)
label.font = .systemFont(ofSize: 130)
label.textColor = UIColor.black
view.addSubview(label)
Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: <#T##Selector#>, userInfo: <#T##Any?#>, repeats: <#T##Bool#>)
#objc func updateLabel() { // ERROR #objc can only be used with members of classes...
if count > 0 {
count -= 1
label.text = "\(count)"
}
}
}
}
Your mistake is that you have put the selector updateLabel inside of viewDidLoad. You should put it outside viewDidLoad so that it is a member of your class, rather than a local function.
To access the label in updateLabel, simply move the declaration of the label outside of both methods.
You should also add a timer parameter to updateLabel so that you can stop the timer when count reaches 0, rather than keeping the timer running forever.
var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
label = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 150))
label.center = CGPoint(x: 250, y: 430)
label.font = .systemFont(ofSize: 130)
label.textColor = UIColor.black
view.addSubview(label)
Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateLabel), userInfo: nil, repeats: true)
}
#objc func updateLabel(_ timer: Timer) {
if count > 0 {
count -= 1
label.text = "\(count)"
} else {
timer.invalidate()
}
}

use timer to countdown from what is placed in the uitextfield

My swift code below should take whatever number is placed in the textfield and then count it down in by a single second. I dont know how to take what is in the textfield and get it to be counted down from. Dont worry about making sure the user places a number and not a string in the textfield.
import UIKit
class ViewController: UIViewController {
var enterTime = UITextField()
var lblTime = UILabel()
var startBTN = UIButton()
var timer = Timer()
var counter = 33
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
[enterTime,lblTime,startBTN].forEach{
$0.backgroundColor = .systemRed
view.addSubview($0)
$0.translatesAutoresizingMaskIntoConstraints = false
}
enterTime.frame = CGRect(x: view.center.x-115, y: view.center.y-200, width: 60, height: 50)
lblTime.frame = CGRect(x: view.center.x-115, y: view.center.y, width: 60, height: 50)
startBTN.frame = CGRect(x: view.center.x-115, y: view.center.y+200, width: 60, height: 50)
startBTN.addTarget(self, action: #selector(startHit), for: .touchDown)
}
#objc func startHit() {
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
}
#objc func timerAction() {
//This is where the user would take the time from uitextfield and causes it to count down
enterTime.text = counter
lblTime.text = "\(counter)"
}
}
1 ) Invalidate your timer and initiate counter with a value from enterTime textField and start your timer in startHit function.
2 ) In the timerAction function, reduce the counter value by 1 and set it in the lblTime.
You may need to modify your startHit and timerAction functions as follows.
#objc func startHit() {
timer.invalidate()
if let counterText = enterTime.text, let counterValue = Int(counterText) {
counter = counterValue
lblTime.text = String(counter)
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
}
}
#objc func timerAction() {
counter -= 1
lblTime.text = String(counter)
if ( counter == 0 ) {
timer.invalidate()
}
}

If statements for code generated buttons, Swift

I have read a lot on Staked Overflow and watched youtube videos about generating buttons with code, but I can't figure out how to have an if statement based off the button. This is nested inside of another statement because when one question is answered with the oringal yes or no buttons I have another question is asked.
I have:
var btn = UIButton(frame: CGRectMake(50, 50, 150, 20));
btn.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal);
btn.setTitle("My Button Text!!", forState:UIControlState.Normal);
btn.addTarget(self, action: "buttonTapped:", forControlEvents: UIControlEvents.TouchUpInside);
self.view.addSubview(btn);
func buttonTapped(sender: UIButton!) {
println("Button Tapped!!!")
}
But rather than printing "Button Tapped!!!" I get a "SIGABART" error. How could I use an if statement instead of a function one? Is there a better way to wright this function statement?
The full code is:
//
// ViewController.swift
// Living Vermont
//
// Created by Matthew Furtsch on 6/8/15.
// Copyright (c) 2015 Matthew Furtsch. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
var label1: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
label1 = UILabel()
label1.text = "Is it a plant?"
label1.font = UIFont.systemFontOfSize(36)
label1.sizeToFit()
//Label location quardnets
label1.center = CGPoint(x: 100, y: 0)
view.addSubview(label1)
UIView.animateWithDuration(1.5, delay: 0.0, usingSpringWithDamping: 0.2, initialSpringVelocity: 0.0, options: nil, animations: {
self.label1.center = CGPoint(x: 100, y: 0 + 40)
}, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func journal(sender: AnyObject)
{
}
#IBAction func noButton(sender: AnyObject)
{
label1.text = "no"
var btn = UIButton(frame: CGRectMake(50, 50, 150, 20));
btn.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal);
btn.setTitle("My Button Text!!", forState:UIControlState.Normal);
btn.addTarget(self, action: "buttonTapped:", forControlEvents: UIControlEvents.TouchUpInside);
self.view.addSubview(btn);
func buttonTapped(sender: UIButton!) {
println("Button Tapped!!!")
}
}
#IBAction func yesButton(sender: AnyObject)
{
label1.text = "yes"
}
}
My guess is that your buttonTapped function is nested inside another method like viewDidLoad. It needs to be a top-level method of your view controller class. Move your buttonTapped method up so it is inside your class, but not inside any methods inside your class.
You should edit your question and include the entire crash message you are getting, along with the stack trace. That might help us tell what's going wrong.

View does not animate

I have a view, which shall move up like a drawer from the bottom of the screen. But it does not do anything. It just sits there =)
Can anyone please tell me, why it is doing that?
This is my code:
import UIKit
class InfoPopUpVC: UIViewController {
var superView: UIView!
var labelText: String!
let textLabel = UILabel()
let height = CGFloat(80)
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
UIView.animateWithDuration(0.4, animations: { () -> Void in
self.view.center.y = 50
})
}
override func viewDidLoad() {
super.viewDidLoad()
setupTextLabel()
view.frame = CGRectMake(0, superView.frame.maxY-height, superView.frame.width, height)
AnimationHelper.blurBackgroundForView(view)
view.backgroundColor = .greenColor()
}
func setupTextLabel(){
textLabel.text = labelText
textLabel.frame = CGRectMake(0, 0, view.frame.width, view.frame.height)
textLabel.numberOfLines = 3
textLabel.textAlignment = .Center
textLabel.frame.inset(dx: 10, dy: 8)
textLabel.sizeToFit()
textLabel.font = UIFont(name: "HelveticaNeue-Light", size: 17)
textLabel.textColor = .whiteColor()
view.addSubview(textLabel)
}
}
Try to put your code as follow inside viewDidAppear or viewWillAppear and with dispatch async. Otherwise your animation might not work.
override func viewDidAppear(animated: Bool) {
dispatch_async(dispatch_get_main_queue(), {
UIView.animateWithDuration(0.4, animations: { () -> Void in
self.view.center.y = 50
})
})
}
You cannot animate a frame or similar property, if the UIViewis constrained using autolayout.
You have two options:
Get rid of autolayout and animate the frames Directory
Use autolayout and animate the constraints (e.g. via outlets)
See the following links for examples:
How do I animate constraint-changes
IOS: ANIMATING AUTOLAYOUT CONSTRAINTS

How to hide keyboard with programmatically created uitextfield

I've programmatically created a uitextfield called "myTextField" in "viewDidLoad".
When I create a function to hide the keyboard when the user taps anywhere on the screen, "myTextField" isn't recognized by xcode. Is it because the textfield is created inside "viewDidLoad"?
Is there any way to access and use "myTextField" outside "viewDidLoad"?
Update: I finally had a chance to go home and copy my code to show what I mean. Here is my code:
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate {
#IBOutlet var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
// Prepare keyboard notifications
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil);
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardDidHideNotification, object: nil);
let screenSize: CGRect = UIScreen.mainScreen().bounds
let screenWidth = screenSize.width;
let screenHeight = screenSize.height;
let myTextView : UITextField = UITextField(
frame : CGRect(x:10, y:(screenHeight/2), width:(screenWidth-20), height: (screenHeight/3) ) )
myTextView.backgroundColor = UIColor( red: 0.5, green: 0.5, blue:0, alpha: 1.0 )
self.scrollView.addSubview( myTextView )
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// Call this method somewhere in your view controller setup code.
func keyboardWillShow(sender: NSNotification) {
let dict:NSDictionary = sender.userInfo as NSDictionary
let s:NSValue = dict.valueForKey(UIKeyboardFrameEndUserInfoKey) as NSValue;
let rect :CGRect = s.CGRectValue();
self.scrollView.contentOffset = CGPoint(x: 0, y: rect.height)
}
func keyboardWillHide(sender: NSNotification) {
let dict:NSDictionary = sender.userInfo as NSDictionary
let s:NSValue = dict.valueForKey(UIKeyboardFrameBeginUserInfoKey) as NSValue;
let rect :CGRect = s.CGRectValue();
self.scrollView.contentOffset = CGPoint(x: 0, y: 0)
}
I've created a UITextView programmatically because I'm struggling with auto layout in Xcode 6. In the meantime I've updated to Xcode beta 5 (from 4) and now even my scrollview is acting weird. So maybe I have to create it with code as well.
How can I access my textview outside of function viewDidLoad?
Declare it as a property of that class, then you can access it from anywhere. Otherwise its scope is limited to the viewDidLoad function and you can't access it from outside.
class YourClass {
var myTextField:UITextField
override func viewDidLoad() {
//init myTextField
}
func test() {
//do something with myTextField
}
}
Use this one to dismiss keyboard :-
UIApplication.sharedApplication().sendAction("resignFirstResponder", to:nil, from:nil, forEvent:nil)