Does anyone know what is wrong with this code? - ios

I'm going to jump straight to the point. My App has crashed and I have no clue what's wrong with it. I thing that is most likely incorrect is the part with the screen size but I don't really think so. Here are my screen size variables:
let screenSize: CGRect = UIScreen.mainScreen().bounds
let screenWidth = screenSize.width - CGFloat(screenSize.width)
let screenHeight = screenSize.height - CGFloat(screenSize.height)
They are being used here, in my tick from my NSTimer:
func tick()
{
let color = Int(arc4random_uniform(3))
if(color == 1)
{
let newDrop:Drop = Drop(dropType: DropType.blue, xPos: Int(arc4random_uniform(UInt32(screenWidth - 5))))
drops.append(newDrop)
} else if(color == 2)
{
let newDrop:Drop = Drop(dropType: DropType.red, xPos: Int(arc4random_uniform(UInt32(screenHeight - 5))))
drops.append(newDrop)
}
drawDrops(drops)
}
The drawDrops function is:
func drawDrops(drops:[Drop])
{
for(var i = 0; i < drops.count; i++)
{
print("Hello, World!")
let button:UIButton = UIButton()
if(drops[i].dropType == DropType.red)
{
button.setImage(UIImage(named: "RedDrop.png"), forState: UIControlState.Normal)
button.addTarget(self, action: Selector("redPressed:"), forControlEvents: UIControlEvents.TouchUpInside)
} else if(drops[i].dropType == DropType.blue)
{
button.setImage(UIImage(named: "BlueDrop.png"), forState: UIControlState.Normal)
button.addTarget(self, action: Selector("bluePressed:"), forControlEvents: UIControlEvents.TouchUpInside)
}
button.frame = CGRectMake(CGFloat(drops[i].xPos), 10, 20, 20)
self.view.addSubview(button)
}
}
Does anyone have any ideas? I'm getting this error that I've never even heard of and have no idea what to do or change:
2016-02-03 18:55:26.679 #Project Name#[19295:1104595] Unknown class Mai
in Interface Builder file. (lldb)
Thanks!
-Jack
EDIT:
I figured out the part with the 'Mai' but now I'm getting a crash with just 'llbd.' The console literally doesn't say anything else:
I'm pretty sure it's something in the tick() function because it takes a second to crash when it enters the view controller and my NSTimer is set to 1 second...
(Not sure if this helps or has to do with anything but it has this line selected as EXC_BAD_INSTRUCTION:
let newDrop:Drop = Drop(dropType: DropType.red, xPos: Int(arc4random_uniform(UInt32(screenHeight - 5))))
)
Answer?
Don't know why this worked but I pulled out the arc4random from he Drop object and made it into its own variable. I don't know why this worked but in happy. :-)

Your crash refers to Interface Builder. I suspect you've got a view with a custom class that no longer exists (or you've mis-typed it - I don't know what 'Mai' is).
Find which view it is and fix the issue in the 'Identity Inspector'. Going by the error message, it sounds like it doesn't have anything to do with the code you posted.

Related

UIActivityIndicator add AppDelegate

I want to run UIActivityIndicator when the application is opened. How can I do this? My code is the way I share it down there. I want this code to work when Launchscreen opens.
#objc func buttonTapped(_ sender: UIButton) {
let size = CGSize(width: 30, height: 30)
let selectedIndicatorIndex = sender.tag
let indicatorType = presentingIndicatorTypes[selectedIndicatorIndex]
startAnimating(size, message: "Loading...", type: indicatorType, fadeInAnimation: nil)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1.5) {
NVActivityIndicatorPresenter.sharedInstance.setMessage("Authenticating...")
}
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
self.stopAnimating(nil)
}
}
for (index, indicatorType) in presentingIndicatorTypes.enumerated() {
let x = 150
let y = 250
let frame = CGRect(x: x, y: y, width: 100, height: 100)
let activityIndicatorView = NVActivityIndicatorView(frame: frame,
type: .orbit)
let animationTypeLabel = UILabel(frame: frame)
activityIndicatorView.padding = 20
if indicatorType == NVActivityIndicatorType.orbit {
activityIndicatorView.padding = 0
}
self.view.addSubview(activityIndicatorView)
self.view.addSubview(animationTypeLabel)
activityIndicatorView.startAnimating()
let button: UIButton = UIButton(frame: frame)
button.tag = index
#if swift(>=4.2)
button.addTarget(self,
action: #selector(buttonTapped(_:)),
for: .touchUpInside)
#else
button.addTarget(self,
action: #selector(buttonTapped(_:)),
for: UIControlEvents.touchUpInside)
#endif
self.view.addSubview(button)
}
What you are trying to achieve is to show UIActivityIndicator during launch screen, which is unfortunately NOT possible. If you want to do any animations on launch screen, use your first view controller as splash screen and redirect to main screen when animation on splash screen ends.
Some ideas:
Create separate loading page and call it from didFinishLaunchingWithOptions method in App delegate
Add loading indicator (can be whatever you want) to it
Set timer of 2-3 seconds, when it ends redirect to your main screen
P.S. delaying application launch just to show users some awesome animation/loading screen is not a good idea. For a first time app users it might seem cool and such, but with an extensive use of an application users might get frustrated waiting even few seconds each time an application is launched.
Good luck :)

cosmicmind material swift MenuView not closing

I am using cosmicmind material swift library and am following the examples code to try to get the FAB MenuView working.
I have copied the code and added the buttons i want, to test i am just testing with 2 buttons. The problem I am facing is with the handleMenu function:
/// Handle the menuView touch event.
internal func handleMenu() {
if menuView.menu.opened {
menuView.close()
(menuView.menu.views?.first as? MaterialButton)?.animate(MaterialAnimation.rotate(rotation: 0))
} else {
menuView.menu.open() { (v: UIView) in
(v as? MaterialButton)?.pulse()
}
(menuView.menu.views?.first as? MaterialButton)?.animate(MaterialAnimation.rotate(rotation: 0.125))
}
}
The full code for this UINavigationController:
import UIKit
import Material
class MyTeeUpsController: UINavigationController {
/// MenuView reference.
private lazy var menuView: MenuView = MenuView()
/// Default spacing size
let spacing: CGFloat = 16
/// Diameter for FabButtons.
let diameter: CGFloat = 56
/// Handle the menuView touch event.
internal func handleMenu() {
if menuView.menu.opened {
menuView.close()
(menuView.menu.views?.first as? MaterialButton)?.animate(MaterialAnimation.rotate(rotation: 0))
} else {
menuView.menu.open() { (v: UIView) in
(v as? MaterialButton)?.pulse()
}
(menuView.menu.views?.first as? MaterialButton)?.animate(MaterialAnimation.rotate(rotation: 0.125))
}
}
/// Handle the menuView touch event.
internal func handleButton(button: UIButton) {
print("Hit Button \(button)")
}
private func prepareMenuView() {
//let w: CGFloat = 52
var img:UIImage? = MaterialIcon.cm.add?.imageWithRenderingMode(.AlwaysTemplate)
let button1: FabButton = FabButton()//frame: CGRectMake((view.bounds.width - w)-10, 550,w,w))
button1.setImage(img, forState: .Normal)
button1.setImage(img, forState: .Highlighted)
button1.pulseColor = MaterialColor.blue.accent3
button1.backgroundColor = MaterialColor.blueGrey.lighten1
button1.borderColor = MaterialColor.blue.accent3
button1.borderWidth = 1
button1.addTarget(self, action: #selector(handleMenu), forControlEvents: .TouchUpInside)
menuView.addSubview(button1)
img = UIImage(named: "filing_cabinet")?.imageWithRenderingMode(.AlwaysTemplate)
let button2:FabButton = FabButton()
button2.depth = .None
button2.setImage(img, forState: .Normal)
button2.setImage(img, forState: .Highlighted)
button2.pulseColor = MaterialColor.blue.accent3
button2.borderColor = MaterialColor.blue.accent3
button2.borderWidth = 1
button2.backgroundColor = MaterialColor.blueGrey.lighten1
button2.addTarget(self, action: #selector(handleButton), forControlEvents: .TouchUpInside)
menuView.addSubview(button2)
menuView.menu.direction = .Up
menuView.menu.baseSize = CGSizeMake(diameter, diameter)
menuView.menu.views = [button1,button2]
view.layout(menuView).width(diameter).height(diameter).bottomRight(bottom: 58, right: 20)
}
private func prepareTabBarItem() {
//todo
}
override func viewDidLoad() {
super.viewDidLoad()
prepareMenuView()
}
}
The menu I have embedded as a subView of UINavigationController. The reason I have added to this subView is because the FAB is on top of a search/display controller (TableView) and this way the FAB can remain on top of the TableView even when scrolling the contents of the Table.
When the view initially loads, I can click on the menu button and the animation happens correctly and button2 appears. However, it does not allow me to hit the second button OR close the menu by pressing button1 again UNLESS I navigate to another tab in the tab bar controller and then navigate back to the tab where the FAB MenuView was located. I am loading my prepareMenuView() function in viewDidLoad just as it is shown in the example.
Not sure how to modify this so that it can behave as desired. It doesn't make sense to pick another ViewController lifecycle method to run prepareMenuView().
so the issue with your code is that button2 only has the selector handler for handleButton. The handleMenu handler is not added to it. So you have two solutions.
Add the handleMenu call to the handleButton
internal func handleButton(button: UIButton) {
print("Hit Button \(button)")
handleMenu(button)
}
Add a selector handler to the button2 instance for handleMenu.
button2.addTarget(self, action: #selector(handleMenu), forControlEvents: .TouchUpInside)
button2.addTarget(self, action: #selector(handleButton), forControlEvents: .TouchUpInside)
Either option will work, just remember that order matters. So if you want the menu to close before you load some content, then call the method before or add the selector handler handleMenu before you add the handleButton.
:) All the best!

Unable to add target to UIButton

I have a UIButton that I created programmatically. I have added a target to it, but it doesn't seem to be running properly. Here is my code (This is a custom class of UIView):
override init(frame: CGRect) {
super.init(frame: frame)
print("targets:")
print(clickButton.allTargets())
clickButton.addTarget(self, action: #selector(self.clickPicture), for: .touchUpInside)
print("targets:")
print(clickButton.allTargets())
}
This is what prints as a result:
As you can see, adding a target to my button does not make a difference. Here is the clickPicture function:
func clickPicture() {
print("clickpicture")
}
Again, this does not print. Does anybody know how to fix this error? Thanks!
Edit:
Definition for clickButton (in my custom class):
var clickButton = UIButton()
Other properties defined in the init:
clickButton.frame.size = CGSize(width: 100, height: 100)
clickButton.layer.cornerRadius = clickButton.frame.size.width / 2
clickButton.layer.borderColor = UIColor.white().cgColor
clickButton.layer.borderWidth = 2.5
clickButton.layer.backgroundColor = shadeColor.cgColor
clickButton.center.x = self.center.x
clickButton.center.y = self.frame.size.height - clickButton.frame.size.height// + 40
clickButton.addTarget(self, action: #selector(self.clickPicture), for: .touchUpInside)
self.addSubview(clickButton)
The button was not on top of the custom view when I instantiated it. I changed its position, and it worked fine.
You have to change this line
clickButton.addTarget(self, action: #selector(self.clickPicture), for: .touchUpInside)
to this
clickButton.addTarget(self, action: #selector(YourClassName.clickPicture), forControlEvents: UIControlEvents.TouchUpInside)
And the method should be
func clickPicture() {
print("clickpicture")
}

Change tint image color when pressing uibutton in Swift

I have a scrollview inside a view. Inside the scrollview I create programmatically 5 buttons. Every button loads a different image with a different tag each one. I added a function that is called when pressing the buttons.
let avatarsListScrollingView = avatarsListView(CGSizeMake(70.0, 55.0), avatarCount: 5)
func avatarsListView(buttonSize:CGSize, avatarCount:Int) -> UIView {
**CODE**
for i in 0...(avatarCount-1) {
let button = UIButton(type: .Custom)
**CODE**
button.setImage(UIImage(named: avatarsList[i]), forState: .Normal)
button.tag = i
button.addTarget(self, action: "avatarListSelected:", forControlEvents: .TouchUpInside)
avatarButtonView.addSubview(button)
}
return avatarButtonView
}
Then when pressing the buttons, I call to "avatarListSelected":
func avatarListSelected(sender:UIButton){
if let image = sender.imageView?.image?.imageWithRenderingMode(.AlwaysTemplate) {
sender.setImage(image, forState: .Normal)
sender.tintColor = UIColor.redColor()
}
self.addAvatarView.reloadInputViews()
}
This function tints the image button to red, it is working fine, but the problem is that when I press some other button, I want the other one goes to the original color. Right now every button that I press gets in red.
I tried to add the call to "self.addAvatarView.reloadInputViews()" to try to "redraw" again all the buttons, but never gets called.
Do you guys know some way to do this?
Thanks to everybody!
This is the final code that solved the problem:
func avatarListSelected(sender:UIButton){
print(sender.tag)
if let image = sender.imageView?.image?.imageWithRenderingMode(.AlwaysTemplate) {
sender.setImage(image, forState: .Normal)
sender.tintColor = UIColor.redColor()
}
for view in self.avatarButtonView.subviews as [UIView] {
if let btn = view as? UIButton {
if btn.tag != sender.tag {
btn.setImage(UIImage(named: avatarsList[btn.tag]), forState: .Normal)
}
}
}
}
Create a property selectedButton: UIButton? and keep a reference to the selected button there. Don't forget to update it in avatarListSelected method and before you change it, if it isn't nil, change its color to original (and then change it).
If the buttons have different original colors, subclass UIButton class and keep the original color there.
I don't know if is better approach or answer, but, i maybe could delivery this using this approach:
Create a method that will "fill" the color for your choice button and "clear" color to others , but its a method that loop through UIScrollView and look for each UIButton. Something like this :
func setBackgroundColorButton(color:UIColor , buttonTag:Int){
for view in self.scrollView.subviews as [UIView] {
if let btn = view as? UIButton {
if btn == buttonTag {
btn.tintColor = color
} else {
btn.tintColor = UIColor.whiteColor()
}
}
}
}
This is the concept, i didn't tested, but maybe just need adjust to search inside your scroll view or similar.
But with this will be work nice i believe :D
You could do it like this
for i in 0...5 {
let button = UIButton(type: .Custom)
let x = 50 * i + 10
let y = 50
button.frame = CGRectMake(CGFloat(x), CGFloat(y), 40, 40)
button.setTitle("\(i)", forState: .Normal)
button.tag = i
button.backgroundColor = UIColor.greenColor()
button.tintColor = UIColor.blueColor()
button.addTarget(self, action: "avatarListSelected:", forControlEvents: .TouchUpInside)
self.view.addSubview(button)
}
func avatarListSelected(sender : UIButton){
sender.backgroundColor = UIColor.orangeColor()
for view in self.view.subviews{
if(view.isKindOfClass(UIButton)){
let button = view as! UIButton
if button.tag != sender.tag{
button.backgroundColor = UIColor.greenColor()
}
}
}
}
The frame etc is just for demonstation purpose only, you should of course use your own value. The tintColor property is not valid for all button types. Read the documentation for more information.

Swift Link Button to Controller

I have a programatically made button, which i would like to connect it to an action so that it goes straight to another view when I click it. Normally i would just control + drag. but i can't since it programatically made. How would i link this code to my "ViewController" so when i click it, the ViewController(log-in screen) Pops up.
The Code is here, and its from https://github.com/mamaral/Onboard
let thirdPage: OnboardingContentViewController = OnboardingContentViewController(title: "Seriously Though", body: "Kudos to the photographer.", image: UIImage(named:"yellow"), buttonText: "Let's Get Started"){ //Enter Action Here//
I'm not sure whether this part is necessary to help you, but i'll link it just in case
if (countElements(self.buttonText) != 0) {
var actionButton: UIButton = UIButton(frame: CGRectMake((CGRectGetMaxX(self.view.frame) / 2) - (contentWidth / 2), CGRectGetMaxY(self.view.frame) - kDefaultMainPageControlHeight - kDefaultActionButtonHeight - self.bottomPadding, contentWidth, kDefaultActionButtonHeight))
actionButton.titleLabel?.font = UIFont .systemFontOfSize(24)
actionButton.setTitle(self.buttonText, forState: .Normal)
actionButton.setTitleColor(self.buttonTextColor, forState: .Normal)
actionButton.addTarget(self, action: "handleButtonPressed", forControlEvents: .TouchUpInside)
self.view.addSubview(actionButton)
Going off of this line of code:
actionButton.addTarget(self, action: "handleButtonPressed", forControlEvents: .TouchUpInside)
If it isn't working, you probably forgot to add an actual function titled "handleButtonPressed"--something like this:
func handleButtonPressed() {
// Show the view that needs showing
}

Resources