Swift: animating uilayoutconstraints and changing alpha causes crash - swift

Why is this code causing a SIGABT error?
#IBAction func showDial(_ sender: Any) {
var dialBottom:CGFloat = lcDialBottom!.constant
if dialBottom == -600 {
//move up
dialBottom = -400
} else {
//move down
dialBottom = -600
}
UIView.animate(withDuration: 0.3,
animations: {
self.lcDialBottom.constant = dialBottom
self.view.layoutIfNeeded()
self.view.updateConstraintsIfNeeded()
self.btnShowDial.alpha = 0.0
})
}
Error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSLayoutConstraint setAlpha:]: unrecognized selector sent to instance 0x600002ff8d70'
I understand what the error is saying, NSLayoutConstraint does not have a setAlpha method, but I'm not calling it on a NSLC, I'm calling set alpha on a UIButton, which does have a setAlpha.
Here's my properties:
#IBOutlet weak var btnShowDial: UIButton!
#IBOutlet weak var lcDialBottom: NSLayoutConstraint!

Check connection of btnShowDial in storyboard. Maybe you connected this IBOutlet with layout constraint.

Related

Value of type 'SecondPageController' has no member 'miniView'

I got seems similar but little bit different question.
It is about declare size issue, but have small error here.
I think error is related to Main.stroyboard, and tried to change ViewController name and also added 'miniView' to ViewController.
My error is
"Value of type 'SecondPageController' has no member 'miniView'",
Witch is very common error(I looked many of same question with this format), but I think my error is relate to adding some new view or something.
And here is my code.
class SecondPageController: UIViewController {
#IBOutlet weak var mainScrollView: UIScrollView!
var imageArray = [UIImage]()
var currentPage = 0
override func viewDidLoad() {
super.viewDidLoad()
imageArray = [UIImage(named: "bus1")!, UIImage(named: "bus2")!]
for i in 0..<imageArray.count {
let imageView = UIImageView()
imageView.image = imageArray[i]
imageView.contentMode = .scaleAspectFit
let xPosition = self.miniView.frame.width * CGFloat(i)
imageView.frame = CGRect(x: xPosition, y: 0, width: self.mainScrollView.frame.width, height: self.mainScrollView.frame.height)
mainScrollView.contentSize.width = mainScrollView.frame.width * CGFloat(i + 1)
mainScrollView.addSubview(imageView)
}
Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(startAnimating), userInfo: nil, repeats: true)
}
#objc func startAnimating() {
//that line check if the current page is the last one, and set it to the first, otherwise, it increment the currentPage
self.currentPage = (self.currentPage == imageArray.count-1) ? 0 : self.currentPage+1
var newOffset = mainScrollView.contentOffset
newOffset.x = mainScrollView.frame.width * CGFloat(self.currentPage)
self.mainScrollView.setContentOffset(newOffset, animated: true)
}
}
I expecting add something to this error solved.
There is no member miniView in SecondPageController. The error was very precise.
If you wanna use a component named miniView you need a reference to it, you can use 2 approaches:
1 - Storyboard:
Drag a view to your UIViewController and link it to #IBOutlet weak var miniView: UIView!
2 - Programatic:
Instantiate it like: let miniView = UIView()
Since you are using Storyboards, you probably forgot to add an #IBOutletto that view, so use approach 1.

unrecognized selector sent to instance - XCode 9.4.1, Swift 4.0

I'm working through the Stanford Swift Course iOS9 from 2016 and having trouble replicating a UIPinchGestureRecognizer, getting very confused with the Selector code syntax.
Inside Class FaceViewController in FaceViewConroller.Swift:
#IBOutlet weak var faceView: FaceView! {
didSet {
faceView.addGestureRecognizer(UIPinchGestureRecognizer(target: self, action: #selector(changeScale(_:))))
updateUI()
}
}
Inside Class definition of Faceview in FaceView.Swift:
#objc
func changeScale(_ recognizer: UIPinchGestureRecognizer) {
switch recognizer.state {
case .changed,.ended:
scale *= recognizer.scale
recognizer.scale = 1.0
default:
break
}
}
It builds without an error (which took a while) but when it runs the pinch gesture causes an error:
Faceit.FaceViewController changeScale:]: unrecognized selector sent to instance
Thanks.
You have passed the wrong target parameter.
Since the method you want to call (changeScale) is declared in FaceView, the target should be an instance of FaceView, not FaceViewController, since FaceViewController does not have a changeScale method.
So:
faceView.addGestureRecognizer(UIPinchGestureRecognizer(target: faceView, action: #selector(changeScale(_:))))

The program crashes with the following and "lldb" in the debugger - Swift 4 [duplicate]

This question already has answers here:
What does "Fatal error: Unexpectedly found nil while unwrapping an Optional value" mean?
(16 answers)
Closed 4 years ago.
this is a code for a program that behaves like this : When the user presses the button , the UIImage called " The Character" goes up (It changes its y axis). But when I run the program , it doesn't crash but when I press the button called "characterGoesUp" , the program crashes and I get the following in the debugger : "lldb".Why?
Code :
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var TheCharacter: UIImageView!
#IBAction func characterGoesUp(_ sender: Any) {
let xPos = TheCharacter.frame.origin.x
let yPos = TheCharacter.frame.origin.y - 225
let heightCharacter = TheCharacter.frame.size.height
let widthCharacter = TheCharacter.frame.size.width
UIView.animate(withDuration: 1.0, animations: {
self.TheCharacter.frame = CGRect(x: xPos, y: yPos, width: widthCharacter, height: heightCharacter)
}) { (finished) in
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
}
Xcode version : 9.3
EDIT:
The error is this :
"Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value"
Your problem is that the imageView TheCharacter is not properly connected to IB , and because of !
#IBOutlet weak var TheCharacter: UIImageView!
in declaration it crashes as it's nil
//
Open the assistant editor and drag from the image to the ViewController's imageView

Unrecognized selector sent to instance, reason: '-[UITouchesEvent rightView]

My app crashes and throws this error
[UITouchesEvent rightView]: unrecognized selector sent to instance 0x13d5092e0
2016-08-04 17:07:15.569 [3809:1375151]
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITouchesEvent rightView]: unrecognized selector sent to instance 0x13d5092e0'
*** First throw call stack:
(0x180d72db0 0x1803d7f80 0x180d79c4c 0x180d76bec 0x180c74c5c 0x1000e681c 0x1000e6a60 0x185f08be8 0x185f08b64 0x185ef0870 0x185f11360 0x185f07ed8 0x185f00c20 0x185ed104c 0x185ecf628 0x180d2909c 0x180d28b30 0x180d26830 0x180c50c50 0x182538088 0x185f3a088 0x1000f5c88 0x1807ee8b8)
libc++abi.dylib: terminating with uncaught exception of type NSException
I'm trying to make a custom class for hide and show password so that I can use it in any UITextField in any UIViewController.
class HideShowIcon:NSObject {
var showPasswordImage = UIImage(named: "ic_show_password") as UIImage?
var hidePasswordImage = UIImage(named: "ic_hide_password") as UIImage?
func hideShowPasswordButton(hideText:UITextField) {
var hideShowSize: CGSize = "12345".sizeWithAttributes([NSFontAttributeName:UIFont.systemFontOfSize(14.0)])
var hideShow: UIButton = UIButton(type: UIButtonType.System)
hideShow.frame = CGRect(x: 0, y: 0, width: hideShowSize.width, height: hideText.frame.size.height)
hideShow.setImage(hidePasswordImage, forState: UIControlState.Normal)
hideText.rightView = hideShow
hideText.rightViewMode = UITextFieldViewMode.Always
hideShow.addTarget(self, action: #selector(HideShowIcon.hideShowPasswordTextField(_:hideText:)), forControlEvents: UIControlEvents.AllTouchEvents)
}
func hideShowPasswordTextField(sender: AnyObject,hideText:UITextField) {
var hideShow: UIButton = (hideText.rightView as? UIButton)!
if !hideText.secureTextEntry {
hideText.secureTextEntry = true
hideShow.setImage(hidePasswordImage, forState: UIControlState.Normal)
} else {
hideText.secureTextEntry = false
hideShow.setImage(showPasswordImage, forState: UIControlState.Normal)
}
hideText.becomeFirstResponder()
}
}
You can not use selector with many parameters hideShowPasswordTextField(_:hideText:) for UIButton target. You can only use selector with one (or zero) parameter, in which UIButton will put itself: hideShowPasswordTextField(_:)
func hideShowPasswordTextField(sender: UIButton) {
//...
}
To use hideText in this function, you may declare it as property of your class:
var hideText: UITextField!
and assign value to it in class initialization step

swift: timer (every second) + gestureRecognizer crashs the GUI

I have a simple gestureRecognizer. When the gesture is "UP" then the menu slides up. "DOWN": The menu slides down. This works.
I have a timer too. It simply counts a number++ every second. This works, too. But together the timer is crashing my GUI.
The animation starts correctly, but when the timer calls my counter-method it's jumping back to the origin GUI.
What kind of problem is that? I found nothing at google, but I think I searched the wrong words. (English isn't my mothertongue and in german there isn't so much literature...)
Here are fragments of my code:
class ViewController: UIViewController, MKMapViewDelegate{
#IBOutlet weak var swipe: UILabel!
var number: Int = 0
#IBOutlet weak var menuView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
var topSwipe = UISwipeGestureRecognizer(target: self, action: Selector("handleSwipes:"))
var downSwipe = UISwipeGestureRecognizer(target: self, action: Selector("handleSwipes:"))
topSwipe.direction = .Up
downSwipe.direction = .Down
view.addGestureRecognizer(topSwipe)
view.addGestureRecognizer(downSwipe)
var timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "counter", userInfo: nil, repeats: true)
}
func counter() {
number++
swipe.text = "\(number)"
}
func handleSwipes(sender:UISwipeGestureRecognizer) {
if (sender.direction == .Up) {
print("TOP")
var menuPosition = CGPointMake(self.menuView.frame.origin.x, self.menuView.frame.origin.y - 100.0)
UIView.animateWithDuration(0.65, animations: {
self.menuView.frame = CGRectMake(menuPosition.x,menuPosition.y,self.menuView.frame.size.width,self.menuView.frame.size.height)
})
}
if (sender.direction == .Down) {
menuChoose = true
UIView.animateWithDuration(0.65, animations: {
var menuPosition = CGPointMake(self.menuView.frame.origin.x, self.menuView.frame.origin.y + 100.0)
self.menuView.frame = CGRectMake(menuPosition.x,menuPosition.y,self.menuView.frame.size.width,self.menuView.frame.size.height)
})
}
}
}
I tried to lock the timer. So when the gesture begins, then just count the number without swipe.text = "(number)"
The animation goes to end, but after an "unlock" the GUI jumped back to the origin.
Thank u for some codesnippets or keywords that I can search :)
It seems that whenever a UILabel's text property is set, it redraws the view, resulting in resetting menuView's position (perhaps someone can elaborate on the "why" in a comment). If you use auto layout constraints to manipulate the position of menuView, it works. You can do this by setting spaceConstraint.constant += 100 or spaceConstraint.constant -= 100 and then calling
UIView.animateWithDuration(0.65, animations: {
self.view.layoutIfNeeded()
})