I have been learning swift for a short time and designed a simple ios swift app in xcode to open up an alert and display the developer name inside of a label when tapped. The code is posted below. For some reason, on the label.hidden = true, I get an error saying "expected declaration", but nothing else. Why is it getting this error message, and what does it mean?
import UIKit
class ViewController: UIViewController {
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.
}
//declares the label
let label = UILabel(frame: CGRectMake(0, 0, 200, 21))
//should hide the label
label.hidden = true
//next 2 lines center the label
label.center = CGPointMake(160, 284)
label.textAlignment = NSTextAlignment.Center
//puts text into the label
label.text = "This app was developed by me!"
//declares the function
#IBAction func function() {
// declares variable that stores the alert and it's properties
let alertController = UIAlertController(title: "Welcome!", message: "Here is some information about the developer!", preferredStyle: .Alert)
alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
label.hidden = false
}
}
You need to encapsulate it with function.
class ViewController: UIViewController {
let label = UILabel(frame: CGRectMake(0, 0, 200, 21))
override func viewDidLoad() {
super.viewDidLoad()
configureViews()
}
func configureViews() {
//declares the label
//should hide the label
label.hidden = true
//next 2 lines center the label
label.center = CGPointMake(160, 284)
label.textAlignment = NSTextAlignment.Center
//puts text into the label
label.text = "This app was developed by me!"
}
//declares the function
#IBAction func function() {
// declares variable that stores the alert and it's properties
let alertController = UIAlertController(title: "Welcome!", message: "Here is some information about the developer!", preferredStyle: .Alert)
alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
label.hidden = false
}
}
Related
Here is my slider configuration, see that the minimum value is 1, and the preview in xCode show the slider in the right position.
And this is all my code:
import UIKit
class ViewController: UIViewController {
var currentValue: Int = 50
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func showAlert() {
let message = "The value of the slider is: \(currentValue)"
let alert = UIAlertController(
title: "Hello World!",
message: message,
preferredStyle: .alert)
let action = UIAlertAction(
title: "OK",
style: .default,
handler: nil)
alert.addAction(action)
present(alert, animated: true, completion: nil)
}
#IBAction func sliderMoved(_ slider: UISlider) {
currentValue = lroundf(slider.value)
}
}
I am not changing the value of the slider anywere, I tried to only have a view with an slider and the generated code of the view controller, and it did not work, the slider always starts its position at 0.
I have a UIAlertController of action sheet style, it has 2 normal actions and one cancel action, I wanted to have different colors of text for them and cus of this, I subclassed UIAlertController:
class CustomAlertViewController: UIAlertController {
internal var cancelText: String?
private let fontRegular = UIFont(name: "IRANSans", size: 16)
private let fontBold = UIFont(name: "IRANSans-Bold", size: 16)
override func viewDidLoad() {
super.viewDidLoad()
self.view.tintColor = UIColor.black
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
self.findLabel(scanView: self.view)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.findLabel(scanView: self.view)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.findLabel(scanView: self.view)
}
func findLabel(scanView: UIView!) {
if (scanView.subviews.count > 0) {
for subview in scanView.subviews {
if let label: UILabel = subview as? UILabel {
if (self.cancelText != nil && label.text == self.cancelText!) {
DispatchQueue.main.async {
label.tintColor = UIColor.red
label.highlightedTextColor = UIColor.green
label.font = self.fontBold
}
} else {
label.font = self.fontRegular
label.tintColor = UIColor(rgb: 0x2699FB)
label.highlightedTextColor = UIColor.black
}
}
self.findLabel(scanView: subview)
}
}
}
} // class end
so now normal labels has blue color and cancel label has red color. but when I select them, I don't want them to highlight as same color. this is where problem accurs, it seems that the labels highlight as UIAlertController's view.tintColor. does anyone know how can I do what I want? I mean how can I define my own highlight color for different labels?
Jafar Khoshtabiat, see below code for display red text in action sheet, I hope it's helps you. see following link for more details https://nshipster.com/uialertcontroller/
//UIActionSheet
let actionSheet = UIActionSheet(title: "Takes the appearance of the bottom bar if specified; otherwise, same as UIActionSheetStyleDefault.", delegate: self, cancelButtonTitle: "Cancel", destructiveButtonTitle: "Destroy", otherButtonTitles: "OK")
actionSheet.actionSheetStyle = .Default
actionSheet.showInView(self.view)
// MARK: UIActionSheetDelegate
func actionSheet(actionSheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int) {
switch buttonIndex {
...
}
}
//UIAlertController
let alertController = UIAlertController(title: nil, message: "Takes the appearance of the bottom bar if specified; otherwise, same as UIActionSheetStyleDefault.", preferredStyle: .ActionSheet)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) in
// ...
}
alertController.addAction(cancelAction)
let OKAction = UIAlertAction(title: "OK", style: .Default) { (action) in
// ...
}
alertController.addAction(OKAction)
let destroyAction = UIAlertAction(title: "Destroy", style: .Destructive) { (action) in
println(action)
}
alertController.addAction(destroyAction)
self.presentViewController(alertController, animated: true) {
// ...
}
I am trying to add UILabels and other UIView elements on button press and have them act as independent elements but I am having no luck. I can successfully add multiple labels and text fields but when i try to delete them using my gesture recognizer it will only delete the latest UIView element. My full code is posted below. There are two main bugs in my implementation as it is: Creating more than one label or text field at a time causes the gestures to not respond and I can only delete the latest UIView element. Any help is greatly appreciated!
My Model:
import Foundation
import UIKit
class QuizItem: UIViewController{
var alert = UIAlertController()
var labelCountStepper = 0
var tfCountStepper = 0
let gestureRecog = myLongPress(target: self, action: #selector(gestureRecognized(sender:)))
let moveGesture = myPanGesture(target: self, action: #selector(userDragged(gesture:)))
func createLabel(){
var randLabel = UILabel(frame: CGRect(x: 200, y: 200, width: 300, height: 20))
randLabel.isUserInteractionEnabled = true
randLabel.textColor = UIColor .black
randLabel.text = "I am a Test Label"
randLabel.tag = labelCountStepper
gestureRecog.quizItem = randLabel
moveGesture.quizItem = randLabel
randLabel.addGestureRecognizer(self.longPressGesture())
randLabel.addGestureRecognizer(self.movePanGesture())
topViewController()?.view.addSubview(randLabel)
labelCountStepper = labelCountStepper+1
}
func createTextField(){
var randTextField = UITextField(frame: CGRect(x: 200, y: 200, width: 300, height: 35))
randTextField.isUserInteractionEnabled = true
randTextField.backgroundColor = UIColor .lightGray
randTextField.placeholder = "Enter your message..."
randTextField.tag = tfCountStepper
gestureRecog.quizItem = randTextField
moveGesture.quizItem = randTextField
randTextField.addGestureRecognizer(self.longPressGesture())
randTextField.addGestureRecognizer(self.movePanGesture())
topViewController()?.view.addSubview(randTextField)
tfCountStepper = tfCountStepper+1
}
func longPressGesture() -> UILongPressGestureRecognizer {
let lpg = UILongPressGestureRecognizer(target: self, action: #selector(gestureRecognized(sender:)))
lpg.minimumPressDuration = 0.5
return lpg
}
func movePanGesture() -> UIPanGestureRecognizer {
let mpg = UIPanGestureRecognizer(target: self, action: #selector(userDragged(gesture:)))
return mpg
}
#objc func gestureRecognized(sender: UILongPressGestureRecognizer){
if(sender.state == .began){
print("Label Tag #: \(labelCountStepper)")
print("Text Field Tag #: \(tfCountStepper)")
alert = UIAlertController(title: "Remove Item?", message: nil, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Yes", style: .default, handler: { (action) -> Void in
self.gestureRecog.quizItem.removeFromSuperview()
}))
alert.addAction(UIAlertAction(title: "No", style: .cancel){(_) in
})
topViewController()?.present(alert, animated: true, completion: nil)
}
}
#objc func userDragged(gesture: UIPanGestureRecognizer){
let loc = gesture.location(in: self.view)
moveGesture.quizItem.center = loc
}
override func viewDidLoad() {
super.viewDidLoad()
}
func topViewController() -> UIViewController? {
guard var topViewController = UIApplication.shared.keyWindow?.rootViewController else { return nil }
while topViewController.presentedViewController != nil {
topViewController = topViewController.presentedViewController!
}
return topViewController
}
}
My ViewController:
import UIKit
class ViewController: UIViewController {
var labelMaker = QuizItem()
#IBAction func createLabel(_ sender: UIButton) {
labelMaker.createLabel()
}
#IBAction func createTextField(_ sender: UIButton) {
labelMaker.createTextField()
}
override func viewDidLoad() {
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
I also made two subclasses that inherit from UILongPress and UIPan Gesture Recognizers. I'll only post the LongPress because the UIPan is exactly the same - just inherits from UIPan instead of UILongPress.
import Foundation
import UIKit
class myLongPress: UILongPressGestureRecognizer{
var quizItem = UIView()
}
You can achieve that by slighting changing your code as below:
#objc func gestureRecognized(sender: UILongPressGestureRecognizer){
if(sender.state == .began){
print("Label Tag #: \(labelCountStepper)")
print("Text Field Tag #: \(tfCountStepper)")
alert = UIAlertController(title: "Remove Item?", message: nil, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Yes", style: .default, handler: { (action) -> Void in
let selectedView = sender.view
selectedView?.removeFromSuperview()
}))
alert.addAction(UIAlertAction(title: "No", style: .cancel){(_) in
})
topViewController()?.present(alert, animated: true, completion: nil)
}
}
#objc func userDragged(gesture: UIPanGestureRecognizer){
let loc = gesture.location(in: self.view)
let selectedView = gesture.view
selectedView?.center = loc
}
Why is my UITapGestureRecognizer not triggering my function for a UIAlertAction? When I build and run my app for the iOS Simulator, my image will not recognize a tap to trigger the alert.
Any suggestions would be appreciated. Thanks, Swift friends!
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let rect = CGRect(x:20,y:20,width:150,height:100)
let imageView = UIImageView(frame:rect)
let image = UIImage(named:"image.png")
imageView.image = image
// imageView.isUserInteractionEnabled = true
self.view.addSubview(imageView)
let guesture = UITapGestureRecognizer(target: self,action:
#selector(ViewController.singleTap))
imageView.addGestureRecognizer(guesture)
}
func singleTap()
{
let alertView = UIAlertController(title: "Heading", message: "Message!", preferredStyle: .Alert)
let defaultAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alertView.addAction(defaultAction)
self.presentViewController(alertView, animated: true, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Uncommenting this line in your code
// imageView.isUserInteractionEnabled = true.
might work. Add this also
image.multipleTouchEnabled = YES;
tap.numberOfTapsRequired = 1;
I currently have a subview that is created and added to the UIView in ViewDidLoad(). I am attempting to user UIGestureRecognizers to detect a tap and unhide a particular button. My current code:
override func viewDidLoad() {
super.viewDidLoad()
architectView = CustomClass(frame: self.view.bounds)
self.view.addSubview(architectView)
let gestureRecognizer = UITapGestureRecognizer(target: self, action: "handleTap:")
gestureRecognizer.delegate = self
architectView.addGestureRecognizer(gestureRecognizer)
}
func handleTap(gestureRecognizer: UIGestureRecognizer) {
let alert = UIAlertController(title: "Alert", message: "Message", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
The handleTap() function is a simple test to see if the taps are being recognized. This code does not trigger the UIAlert when it is pressed? What am I missing?
I tested your code here and it does work. However, I think you might be missing to add the UIGestureRecognizerDelegate protocol to your View Controller. See below:
class ViewController: UIViewController, UIGestureRecognizerDelegate {
var architectView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
architectView = UIView(frame: self.view.bounds)
self.view.addSubview(architectView)
let gestureRecognizer = UITapGestureRecognizer(target: self, action: "handleTap:")
gestureRecognizer.delegate = self
architectView.addGestureRecognizer(gestureRecognizer)
}
func handleTap(gestureRecognizer: UIGestureRecognizer) {
let alert = UIAlertController(title: "Alert", message: "Message", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Swift 3 version code based on Raphael Silva answer:
import UIKit
class ViewController: UIViewController, UIGestureRecognizerDelegate {
var architectView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
architectView = UIView(frame: self.view.bounds)
self.view.addSubview(architectView)
let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.handleTap(gestureRecognizer:)))
gestureRecognizer.delegate = self
architectView.addGestureRecognizer(gestureRecognizer)
}
func handleTap(gestureRecognizer: UIGestureRecognizer) {
let alert = UIAlertController(title: "Alert", message: "Message", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}