How to use Lottie Animation using storyboard - ios

I'm using the latest version of Xcode.
I have a JSON file whose name is "rainynight".
I want to display it into 'View' component using storyboard.
Below is the code I wrote on my ViewController.
import UIKit
import Lottie
class ViewController: UIViewController {
#IBOutlet weak var animationView: AnimationView!
override func viewDidLoad() {
super.viewDidLoad()
animationView.contentMode = .scaleAspectFit
animationView.loopMode = .loop
animationView.play()
}
and then, I went to attribute inspector to set the Animation View's Animation name.
Screenshot of main.stroyboard
Until now, everything works fine.
The "rainynight" JSON file is shown in the view perfectly fine.
But the problem is that my ultimate goal is displaying several Lottie animations randomly.
Actually, I will connect Lottie animation with weather API but for convenience's sake let's say I want to display JSON files randomly.
For example, I have an array that contains JSON files' name like this.
let jsonArray = ["rainynight", "storm", "foggy"]
I have these JSON files on my file list.
But how do I show randomly one of these elements on the view using storyboard?
I know it can be solved super easily by writing a code.
But by writing a code, as far as I know, I can only set the animation in the center or something else.
I want the animation to be set at the place I exactly want it to be.
The location of the animation view can't be described with just simple word 'center'.
That's why I want to use storyboard.

Put a UIView wherever you want in your storyboard, and change the class name to AnimationView. Drag an outlet to your view controller.
Then the rest is just as easy.
#IBOutlet weak var animationView: AnimationView!
override func viewDidLoad() {
super.viewDidLoad()
let subAnimationView = AnimationView(name: "myAnimationName")
animationView.contentMode = .scaleAspectFit
animationView.addSubview(subAnimationView)
subAnimationView.frame = animationView.bounds
subAnimationView.play()
}

Related

Setting the background of an UIButton programmatically not working

I'm just trying to simply set the background image of the button, but whatever I try it is doing nothing. I also put a UIImageView there to see if there's any issue with the image file, but the image view is set perfectly fine. Do I have to set something in the properties of the button?
Here the code:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let imageToSet = UIImage(named: "3-1")
b1.setBackgroundImage(imageToSet, for: .normal)
imageView.image = imageToSet
}
#IBOutlet weak var b1: UIButton!
#IBOutlet weak var imageView: UIImageView!
}
These are my setting for the button:
In Xcode 13 ,UIButton has four type are Plain,Grain,Tinted,Filled .When you create a button in storyboard , button type automatically set with Plain that means new UIButton configurations is on (If you set one of them 4).So when you try to use old behaviours like
setBackgroundImage(..)
setImage(..)
This functions not gonna effect on this button. So If you want to use old behaviours you need to set style Plain to Default

I want my view controllers to have the same combination of custom UIViews which communicate with each other

I want my several view controllers to have a player in the bottom. This player consists of 2 views: the player and a button which toggles it (can be hidden or expanded).
Now I use the code below in each view controller to add this player.
#IBOutlet weak var broadcastView: BroadcastView!
#IBOutlet weak var broadcastViewBottomConstraint: NSLayoutConstraint!
#IBOutlet weak var avatarImageView: UIImageView!
#IBAction func toggleBroadcastMode(_ sender: ToggleBroadcastButton) {
if sender.isExpanded {
broadcastViewBottomConstraint.hideBroadcastView()
} else {
broadcastViewBottomConstraint.expandBroadcastView()
}
animateBroadcastToggle()
sender.toggle()
broadcastView.toggleBroadcastView()
}
Is there a way not to duplicate the code over and over? Maybe I can create parent VC or View to do it? If so, then how?
I personally would subclass a UINavigationController and have it in there, that way you can navigate through the flow while the player stays looking good at the bottom, if you need a VC to interact with it then you can
if let nav = navigationController as? MyPlayerNavController {
nav.PlayThis()
}
you can have it change size and everything from there and you wont lose it during transitions and stuff like the music app when playing music.
Add it as a subview of the keyWindow. That way it will always stay in all the viewControllers.
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var overlayViewFrame = UIScreen.main.bounds
overlayViewFrame.origin.y = overlayViewFrame.height - 200
overlayViewFrame.size.height = 200
let overlayView = UIView(frame:overlayViewFrame)
overlayView.backgroundColor = UIColor.cyan
UIApplication.shared.keyWindow?.addSubview(overlayView)
}
This code is a sample generic code. If you want certain VCs to not show this, keep this overlay view in a singleton, and hide in appropriate VCs.
Output screenshots:

Changing an image using swift for iOS App

So I am trying to load a picture programmatically using Swift and I am having some trouble. I can change the UIImage of a view using the Attributes Inspector, so I know the picture I am using is added properly and I am using the right name.
Here is the code I am using:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var myPicture: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
myPicture.image = UIImage(named:"myNewPic")
}
}
I think there might be some setting I am missing in Attributes inspector or something since the code is pretty simple and I know the image is added properly.
Any help would be appreciated.
Make sure that your image name is correct. You have image properly in xcode and your outlet is properly connected
add image with extension if you are not using assets for images. like myNewPic.png or myNewPic.jpg whatever extension it is.
So, your code should be like,
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var myPicture: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
myPicture.image = UIImage(named:"myNewPic.png") //or .jpg or else
}
}
another choice
if you load image from assets usemyNewPic if you load from bundle use myNewPic.png (with extensions).
if let img = UIImage(named: "myNewPic") {
myPicture.image = img
} else {
myPicture.image = UIImage(named:"myNewPic.Imageextensions")
}

UISliders and UILabels and viewControllers

How would I be able to increase/decrease the size of my UILabel by using UISlider which is in a different viewController?
I have a viewController1 that has the UILabel1 and I have viewController2 which has a UISlider. With the UISlider I have another label,UILabel2, just to see how big the text will be. I want UILabel1 to increase/decrease also instead of just one label to increase/decrease.
The code being used for UISLider is,
#IBOutlet weak var label: UILabel!
#IBOutlet weak var slider: UISlider!
#IBAction func sizeChanged(sender: UISlider) {
let senderValue = CGFloat(sender.value)
label.font = UIFont(name: label.font.fontName, size: senderValue)
}
This code with UILabel is for viewController2 and I want to change the size of another UILabel thats in viewController1.
This is viewController1:
import UIKit
class ViewController1: ViewController {
#IBOutlet weak var label1: UILabel!
#IBOutlet weak var scrollView1: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
scrollView1.contentSize.height = 5000
scrollView1.contentSize.width = 375
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
This is viewController2:
#IBOutlet weak var label: UILabel!
#IBOutlet weak var slider: UISlider!
#IBAction func sizeChanged(sender: UISlider) {
let senderValue = CGFloat(sender.value)
label.font = UIFont(name: label.font.fontName, size: senderValue)
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
Any help would be great.
In computer programming, when something seems difficult or complicated, you should look for ways to break it down into smaller problems that are easier to solve. Yours is a fine example. You asked:
How would I be able to increase/decrease the size of my UILabel by using UISlider which is in a different viewController?
So, what are the steps that anyone would need to perform to make this happen? There are basically three steps here:
Get a slider's value.
Send a value from one view controller to another.
Use a value to set the size of a label.
How do I get a slider's value? This is straightforward. Set the slider's target to the view controller that manages it and its action to some action in the view controller. That method will be called when the slider changes. The action will look like this:
#IBAction func sliderValueChanged(sender: UISlider) {
let value = sender.value
// do something with the value
}
How do I send data from one view controller to another? There are lots of questions on SO that cover this. Of those, Passing Data Between View Controllers is perhaps the canonical one. There are lots of options, including:
Have one view controller call a method in the other. If the view controller with the slider has a reference to the one with the label, it only has to call some method when the slider changes to pass the new value to the other controller. Or, maybe it's the view controller with the label that has a reference to the one with the slider, which is pretty typical if the slider's controller is created by the label's controller. In that case, the label's controller can call a method to retrieve the value.
Broadcast the data to anyone who is listening using notifications. When the slider changes, it's action can post a notification with the new value. Any object, including the controller with the label, can listen for that notification and act on it.
Use a proper data model. The MVC (model-view-controller) paradigm is big in Cocoa, and if your app is anything beyond trivial it should have its own data model. That model may be a reasonable place to store the slider's latest setting, and the controller with the label can read it from there when its view appears.
Stash the value somewhere. Global variables are a short path to a badly design application, but their simplicity is appealing to beginners. A better choice may be the defaults system, which at least lets the value persist when the app quits.
So, lots of options there. Forget about the slider and the label and think about how the view controllers in your app should communicate with each other. Once you figure that out, the slider setting is just one more thing that they have to say to each other. The style you choose will tell you what to put in the action method above in place of the comment.
How do I set the size of a label? It's a little unclear what you mean by setting the size. Do you want to change the font size, or the width of the label, or the width and height? In any case, there are accessors for all the properties of a label that you might want to set, so check out the docs. When the label's view controller gets a new value via one of the methods above, it should update the appropriate property of the label. You typically connect the label to an IBOutlet property in the view controller to give the controller easy access to the label.
I think, you can look at NSNotificationCenter's functionality, especially at NSNotification's userInfo:
parameter. You can pass your slider's value to userInfo from first VC and then listen to this notification in second VC.
Great example of this method in Objective-C:
https://stackoverflow.com/a/7896761

EXC_BAD_ACCESS when setting properties of an option view property

I'm trying to figure out how to make a UIProgessView (loading Bar) have the color tint of green. I've looked around and there is no working Swift version for this. I am also trying to figure out how to take the bar off of the screen when it's finished. Nothing is done with the storyboard, everything is done programmatically.
I'm trying to customize the bar with this but it says "Bad access".
self.progressView!.tintColor = UIColor.greenColor()
This is where I'm trying to hide the bar, but there is a bad access here as well.
progressView!.hidden = true
The context:
import UIKit
import AVFoundation
class MainController: UIViewController {
var progressView: UIProgressView?
override func viewDidLoad() {
super.viewDidLoad()
addControls()
}
func addControls() {
//----This where it try to change the tint below
self.progressView!.tintColor = UIColor.greenColor()
// Create Progress View Control
progressView = UIProgressView(progressViewStyle: UIProgressViewStyle.Default)
progressView?.center = self.view.center
view.addSubview(progressView!)
}
}
You haven't actually created the UIProgressView before you call self.progressView!.tintColor thus, progressView is nil at this point but you're trying to force unwrap it.
Move the progressView = UIProgressView(...) line up to the top of addControls() and that should solve the problem.

Resources