Mapbox : MGLSymbolStyleLayer add my custom "iconImage" - ios

How can i add custom image for MGLSymbolStyleLayer. Below is my code,
let symbolGraphicsLayer = MGLSymbolStyleLayer(identifier: identifier, source: source)
symbolGraphicsLayer.sourceLayerIdentifier = identifier
symbolGraphicsLayer.iconImageName = MGLStyleConstantValue<NSString>(rawValue: "assets/myImage")
symbolGraphicsLayer.iconScale = MGLStyleValue(rawValue: 1)
symbolGraphicsLayer.isVisible = true
self.mapView.style?.addLayer(symbolGraphicsLayer)
Thanks.

Is your problem that the image doesn't appear?
You first need to add the image to the style layer, and then you can use it.
So before that code, you can do:
if let image = UIImage(named: "myImage") {
mapView.style?.setImage(image, forName: "myImage")
}
and you can use it afterwards like you said. Just use the name you passed to the setImage method.
I hope this helps other people since the documentation is quite poor for this

Related

how to pass [String]' to 'String' value in swift

I am trying to create a slideshow
I follow this zvonicek/ImageSlideshow library.
But I don't know how to pass array of images to it
I have the following code:
let imageSource = [SDWebImageSource(urlString:self.myArray[i])!, ImageSource(image: UIImage(named: "Beach")!)]
slideshow.setImageInputs(imageSource as! [InputSource])
self.myArray[i] contains that kind of value
and I need to pass that array to imageSource.
Essentially, what you are trying to do is to transform each element of a [String] to a SDWebImageSource, so that it forms a [SDWebImageSource]. Right? This is precisely the job of the map method.
let imageSource = self.myArray.map { SDWebImageSource(urlString: $0) }
Or more simply:
let imageSource = self.myArray.map(SDWebImageSource.init))
As mentioned in the loading images section in the description of the library, if you have url for the images. You can use the AlamofireSource or KingfisherSource to create the image Source array.
ImageSource(image: UIImage(named: "myImage"))!,
ImageSource(image: UIImage(named: "myImage2"))!,
AlamofireSource(urlString: "https://images.unsplash.com/photo-1432679963831-2dab49187847?w=1080"),
KingfisherSource(urlString: "https://images.unsplash.com/photo-1432679963831-2dab49187847?w=1080"),
ParseSource(file: PFFile(name:"image.jpg", data:data))
])

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.

how to add image literal to an array and show them?

I was trying to add image literals to array and display them as per the index.
Here is my code :
var images = [#imageLiteral(resourceName: "male-circle-128"),#imageLiteral(resourceName: "add_to_favourite-128"),#imageLiteral(resourceName: "28468-200"),#imageLiteral(resourceName: "progress_circular"),#imageLiteral(resourceName: "logout-1-128")]
and showing like this
cell!.imageView?.image = UIImage.init(cgImage: images[indexPath.row] as! CGImage)
got EXC_BAD_INSTRUCTION! what is the proper way to do this
let images:[UIImage] = [array of image literal goes here]
You can simply create array of image literals like:
var images = [#imageLiteral(resourceName: "image1"),#imageLiteral(resourceName: "image2"]
Why do you cast to CGImage , your literals are UIImage and you can use them without casting and even if you want CGImage use the initializer not casting.
let images = [literal images are here]
imageview.image = images[indexPath.row]

Is there a way to compare button images in Swift/iOS

I've looked around and I don't think there's a way to do this, but what I'm looking for is the ability to compare button images. I have a situation where I want to see if the button is set to a certain image before I change it. The pseudocode would be something like
if (myCell.followButton.image == UIImage(named: "")) {
//do something here
}
Updated for iOS 8 thanks to kakubei
UIButton has a property called currentImage, so use that to compare the images:
iOS 8+
if myCell.followButton.currentImage.isEqual(UIImage(named: "yourImageName")) {
//do something here
}
iOS 7-
if (myCell.followButton.currentImage == UIImage(named: "yourImageName")) {
//do something here
}
A better way to achieve this functionality would be to keep track of the button's selected state and change its image based on that. That would make it more flexible if you ever change the name of the image.
Matt Cooper's solution won't work in iOS 8 because Apple has changed how images are cached. You now need to use .isEqual
As in:
// assuming both button and newButton are UIImage instances
if button.currentImage!.isEqual(newButton) {
...
From Apple Docs:
As of iOS 8, you can no longer rely on pointer equality to compare
cached UIImage objects as the caching mechanism may not return the
same UIImage object, but will have cached image data separately. You
must use isEqual: to correctly test for equality.
The downside of this is that it won't work in iOS 7! I don't know of a way that will work in both but I'm hoping there is, I'm searching for it myself :)
It can be done in following way:
if let btnImage = sender.image(for: .normal),
let Image = UIImage(named: "firstImage.png"), UIImagePNGRepresentation(btnImage) == UIImagePNGRepresentation(Image)
{
sender.setImage(UIImage(named:"secondImage.png"), for: .normal)
}
else
{
sender.setImage( UIImage(named:"firstImage.png"), for: .normal)
}
On iOS 13 #Matt Cooper's answer does not work, I'm not sure but other infos are included in the name of the image (maybe changes in the API since 2015), so my comparison always returns false:
UIImage: 0x28297e880 named (main: Icon-camera-alt) {20, 20}
I've used this in my case:
myButton.currentImage?.description.contains("camera-alt")
Sure, if you keep the image references you can just do a straight compare. Otherwise, I am not aware of a way.

Error when passing an int EXC_BREAKPOINT(code=1 Swift Xcode ios

I'm getting an error when passing a let variable as a tag in a for loop, but not when I replace the variable with a number. I can println(i) and return a number.
Why wont accept it as a key?
I have also tried setting a var as a counter with the same results
I get an error in:
swift_dynamicCastObjCClassUnconditional
full error:
Thread 1: EXC_BREAKPOINT(code=1, subcode=0x1001ee4b0)
func updateThing() {
for (i, img) in enumerate(thingState) {
switch img {
case 0:
image = UIImage(named: "0.png");
break
case 1:
image = UIImage(named: "1.png");
break
case 2:
image = UIImage(named: "2.png");
break
default:
image = UIImage(named: "x.png");
}
thing = self.view.viewWithTag(i) as UIButton;
thing.setImage(image, forState: .Normal);
}
But if I replace the i with a number there is no error and the image with the specified tag changes, and if I println(i) I get a number for each pass
thing = self.view.viewWithTag(2) as UIButton;
You want to be sure your views are Buttons, else it will fail to cast your view.
func updateThing() {
for (i, img) in enumerate(thingState) {
switch img {
case 0:
image = UIImage(named: "0.png");
break
case 1:
image = UIImage(named: "1.png");
break
case 2:
image = UIImage(named: "2.png");
break
default:
image = UIImage(named: "x.png");
}
if let thing = self.view.viewWithTag(i) as? UIButton {
thing.setImage(image, forState: .Normal)
}
}
}
The optional cast operator (as?) is preferred to the cast operator(as) since it doesn't make your app crash when it fails to cast.
Oh and semicolons are useless in Swift :)
EDIT:
In the latest Swift version, as has been replaced with as!, but as still exists.
as! is used to force cast with no check and is prone to craches. You mainly use it to down cast and you're absolutely sure of the type of the object.
as can be used as an upcast such as CAShapeLayer to CALayer or other special cases like [NSObject:AnyObject] to NSDictionary. Making downcast will fail to compile.
The problem is that you do not declare i but take it implicitly from thingState. Without seeing the declaration of the latter it's hard to tell, but I guess you need to do
thing = self.view.viewWithTag(Int(i)) as UIButton
And yes: semicolons are superfluous; as well as the break
This problem is to delete button by your mistake.
and You must see Your StoryBoard Screen or Xib file.
I think You Deleted Button.
I faced the same problem, i tried Shift+Cmd+K to clean the project and it fixed the problem

Resources