for loop animation not working correctly? - ios

I have copied 5 image files into my project, have cast them to the UIImage class from strings (not included below), created an array for them, and tried to loop through that array when I click the updateIMAGE button, to essentially create a little animation. The file in the UIImageView is frame1, but when I try press the button in the simulator it loops straight to the frame5.
var imageArray: [UIImage] = [frame1, frame2, frame3, frame4, frame5]
#IBOutlet var imageView: UIImageView!
#IBAction func updateIMAGE(sender: AnyObject) {
for image in 0..<imageArray.count {
var im = imageArray[image]
imageView.image = im
println(im)
}
}

You can iterate through an array and add an UIImage to array and outside the loop assign that array to the animationImages property of UIImageView, set up duration and run animation:
var array: NSMutableArray = []()
for image in 0..<imageArray.count {
{
array.addObject(imageArray[image])
}
imageView.animationImages = array;
imageView.animationDuration = 1.5
imageView.startAnimating()

To be much more efficient, iOS will combine multiple drawing operations into a single operation, which is 99.99% of the time what developers and their customers want. If you want an animation, you will have to write some code that does animations.
PS. You can iterate directly through an array, you don't need an index variable.

Related

iOS UI Test: Get image filename (Swift)

My question is about getting the filename of image of the UIImage that is used in a UIImageView.
Here is my sample code:
// Using image from UIImageObject
imageView1.image = myUIImage
// Using image from XAssets
imageView2.image = UIImage(named: "myImageName")
In UI Tests, how can I get the name of the image file?
The expected resoult would be:
"myUImageObject" // For imageView1
"myImageName" // For imageView2
Is there any way to get this value?
Thanks everyone!
Unfortunately you can't do that, however there's an easy workaround, try something like this:
let myImageView = UIImageView()
myImageView.image = UIImage(named: "anyImage")
myImageView.restorationIdentifier = "anyImage" // Same name as image's name!
// Later, in UI Tests:
print(myImageView.restorationIdentifier!) // Prints "anyImage"
Basically in this solution you're using the restoration identifier to hold the image's name, so you can use it later anywhere. If you update the image, you must also update the restoration identifier, like this:
myImageView.restorationIdentifier = "newImageName"
I hope that helps you, good luck!
Swift 4
Declare Outlet
#IBOutlet weak var m_SetName_Img: UIImageView! //Image is already set image from Assets File
Declare Function
extension UIImageView {
func getImageName() -> String {
if let image = self.image, let imageName = image.accessibilityIdentifier {
return imageName
} else {
return "nil"
}
}
}
Use
print(self.m_SetName_Img.getImageName())
You can use:
imageView2.image?.imageAsset?.value(forKey: "assetName")
assetName is private API, so officially out of bounds for the App Store, but for testing it should be just fine.

UIButton Background image is not set from Singleton Dictionary

again.
I've just finished a singleton example of a Dictionary with the following code
at the file Recipes.swift
static let sharedInstance = Recipes()
var imagesOfChef = [Int : chefImages]()
struct chefImages {
var objidChef: String!
var imageChef: UIImage!
}
And when a process is finished i have this code
let singleton = Recipes.sharedInstance
singleton.imagesOfChef = self.imagesOfChef
So the singleton has the same dictionary as the imagesOfChef has.
On the next view i want to access all the data of the Dictionary and set a background image of the button with one of the images that the Dictionary has.
So in the cellForItemAtIndexPath I have the following code
let test = userPointer.objectId
let otherReferenceToTheSameSingleton = Recipes.sharedInstance
for i in 0...otherReferenceToTheSameSingleton.imagesOfChef.count - 1 {
print(otherReferenceToTheSameSingleton.imagesOfChef[i]!.objidChef) //it prints the object id's of the Chef normally
if otherReferenceToTheSameSingleton.imagesOfChef[i]!.objidChef == test! {
print("done")
print(otherReferenceToTheSameSingleton.imagesOfChef[i]!.imageChef)
cell.avatarOutlet.setImage(otherReferenceToTheSameSingleton.imagesOfChef[i]!.imageChef, forState: .Normal) //but it doesnt set the Image as a background
}
}
So when the object id of the Chef matches the object id that is inside the Dictionary i want to set as background the image that is in the same row.
But it doesn't!
Although when the if statement is correct if you see i try to print the image and i get
<UIImage: 0x1582c9b50>, {60, 60}
How is it possible to set this image as background??!?!
Thanks a lot!
Set the Button type custom if it is created programmatically
let button = UIButton(type: UIButtonType.Custom) as UIButton
If it is from Stroyboard change the type there.

Swift keep pointer/reference to object or another a pattern?

I am converting a project from another tool and language:
Suppose I have a
singleimagecache: UIImage;
I now pass this to a structure which does
var myimage: UIImage = singleimagecache;
Now, this struct is passed to a function that does some work.
This function determines another image should be cached. In my original code, it would simply use myimage and assign its content some other image-bitmap data. Since the object-reference itself was not changed (only its content) singleimagecache would still point to valid fresh new cache data.
However, this is not possible in Swift since UIImage requires to be reconstructed like this:
myimage = UIImage(...)
But doing that would leave singleimagecache with wrong data
So that leaves me the following options:
Any support in Swift for keeping references in sync?
Any support in Swift for keeping pointers to objects (that themselves possibly can be nillable)
Wrap UIImage inside another object that is persistant and use that.
There is no built-in Swift support for what you wish to do. I would just make a wrapper class with 2 UIImage properties. One would be myimage and the other would be singleimagecache. You could then use the didSet property observer on myimage to achieve the desired synchronization so that singleimagecache will always be up to date with myimage. didSet will be called everytime a new value is stored/set in the property.
class imageCache
{
var myimage:
= UIImage() {
didSet {
singleimagecache = myimage
}
}
var singleimagecache = UIImage()
}

Swift: Array not mutating between classes?

I'm working on a swift project where I create a custom keyboard. In my ViewController, I store and mutate an array of UIImages. Then, in my Keyboard module in my keyboardViewcontroller.swift I would like to use the data I have in this array to create buttons. However, when I try to access the array in KeyBoardViewController it seems to give me an empty array and throws an index out of bounds error. What is strange to me is that in ViewController I print out the size of my array and it is definitely not empty. Here is how I'm storing the array:
import UIKit
class Main {
var pics :[UIImage]
init(pics : [UIImage]) {
self.pics = [UIImage]()
}
}
var instance = Main(pics: [UIImage]())
In ViewController I mutate it with instance.pics.append...
In my KeyboardViewController:
for image in instance.pics {
...
}
Why would this show as an empty array in KeyboardViewController?
Thanks
Rather than assigning an empty array of UIImage objects, the following will set the internal array variable to be a copy of the myPics array.
import UIKit
class Main {
var pics: [UIImage]
init(pics: [UIImage]) {
self.pics = pics
}
}
var instance = Main(pics: myPics)

How can I set the value of this variable?

I want to change the value of a UIImage view.
This is what I've got so far.
import UIKit
import Foundation
struct imageViews {
var Slope1ImageView: UIImage?
var slopeStatus = dataValues()
func setSlope1Image(slopeStatus1: Int) -> UIImage {
var image: String
switch slopeStatus1 {
case 0:
image = "NotWorkingStatus"
default:
image = "WorkingStatus"
}
var statusImage = UIImage(named: image)
return statusImage
}
}
This my setup.
I have a file which gets an object from Parse.
This will either be 0 or 1.
I then assign the 0 or the 1 to a variable in a struct.
In my code above I have created a instance of this struct.
I have then created a function which will take in a variable from my struct and check if it has the value of zero, it then sets the variable image to the respective image. If it doesn't it sets it to a different image.
How do I set the variable of Slope1ImageViews to the image selected by the function in this way.
Slope1ImageView = setSlope1Image(slopeStatus.SlopeStatus1)
each time I try I get an error along the lines of
cannot assign to "Slope1ImageView" in "self"
I'm at my wits end!
Any help would be greatly appreciated.
I think your problem is with Slope1ImageView. If the first letter is uppercased, Swift assumes you're referring to a class. Furthermore, you need to assign the local to either a variable or a constant. Structs should also have the first letter uppercased. Assuming everything else is set up correctly, you probably just need to do something like this.
struct ImageViews {
// existing code...
}
var instanceOfStruct = ImageViews()
var slope1imageView: UIImage = instanceOfStruct.setSlope1Image(slopeStatus.SlopeStatus1)
There's a lot going on here, I'll touch on some.
Declaration
You shouldn't be using a struct. Images are rather large objects in general and you don't want them to be copied across your app. They should remain reference types and be in a class. Structs/Classes should also be capitalized to adhere to common practice, while properties should be lower case. You also have your name as a plural which implies that it is an array, it shouldn't be this way. Also, don't name something imageView unless its an imageView. On that same line, don't name something image if it's a string. Also, don't prefix a function with set unless it sets something. Your function returns something, so a get prefix is probably better. I feel like you want to set the image within self, so let's do that. So first step is to change this:
struct imageViews {
var Slope1ImageView: UIImage?
var slopeStatus = dataValues()
func setSlope1Image(slopeStatus1: Int) -> UIImage {
var image: String
switch slopeStatus1 {
case 0:
image = "NotWorkingStatus"
default:
image = "WorkingStatus"
}
var statusImage = UIImage(named: image)
return statusImage
}
}
To this:
class SlopeStatus {
var slope1Image: UIImage?
var slopeStatus = dataValues()
func setSlope1Image(slopeStatus1: Int) {
var imageString: String
switch slopeStatus1 {
case 0:
image = "NotWorkingStatus"
default:
image = "WorkingStatus"
}
slope1Image = UIImage(named: image)
}
}
Assignment
You're trying to assign a UIImage to a Class with this:
Slope1ImageView = setSlope1Image(slopeStatus.SlopeStatus1)
With the changes above, it should probably be
var slopeStatusImageObject = SlopeStatus()
slopeStatusImageObject.setSlope1Image(slopeStatus.SlopeStatus1)

Resources