I have my background image set by self.view.insertSubview. I'm trying to create a UISwipeGestureRecognizer that advances through the background Image on swipe, while another image array cycles on tap. The tap image works fine but the swipe image only works on the first swipe.
Here's the gesture recognizer:
let gestureRecognizerBackground = UISwipeGestureRecognizer(target: self, action: #selector(changeBackground))
dragon2View.addGestureRecognizer(gestureRecognizerBackground)
and here's the changeBackground func:
func changeBackground() {
let backgroundImageArray = [#imageLiteral(resourceName: "artic.png"),#imageLiteral(resourceName: "beach.png"),#imageLiteral(resourceName: "mountain.jpg"),#imageLiteral(resourceName: "spring.png")]
let randomBackground = Int(arc4random_uniform(UInt32 (backgroundImageArray.count)))
let backgroundImage = UIImageView(frame: UIScreen.main.bounds)
backgroundImage.image = backgroundImageArray[randomBackground]
self.view.insertSubview(backgroundImage, at: 0)
}
Not sure why it's not advancing. Thanks in advance for your comments.
I was trying to set the background image with self.view.insertSubview because I didn't realize I could just have two views and 'send to back'. No problem with the array now.
Related
I have an image, I convert it into a 360 panoramic image, using metal (https://github.com/ejeinc/MetalScope). How can I add a button on the door (see the screenshot) so that by clicking on it, it would go to the next controller with a different panoramic image (another room)
github project : https://github.com/Mahnach/MetalRender
You can add a tap gesture recogniser to the image, then get the point where image is tapped. If it is tapped near the door, perform segue to the next controller. If you're not sure where the door area is, you can print out the touch point & see where on the image you're tapping.
override func viewDidLoad() {
super.viewDidLoad()
//Create Tap Gesture
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapAction(_:)))
//Enable image user interaction
self.imageView.isUserInteractionEnabled = true
//Add Tap gesture to the image
self.imageView.addGestureRecognizer(tapGestureRecognizer)
}
#objc func tapAction(_ sender: UITapGestureRecognizer){
//Get the touch point
let touchPoint = sender.location(in: self.imageView)
//Set the door area
let doorArea = CGRect(x: 200.0, y: 100.0, width: 75.0, height: 100.0)
//Then check if touch point is near door
if doorArea.contains(touchPoint){
//Peform segue
performSegue(withIdentifier: "nextScene", sender: nil)
}
}
I currently have an image set into my UIImageView the following way:
art_image.image = UIImage(named:(artworkPin.title!))
where art_image is the image View and artworkPin.title refers to the name of the image. However, I want to add a second image to the UIImageView if it exists I thought of programming it as
art_image.image = UIImage(named:(artworkPin.title + "1")?)
would this work? In this case I would name a second image the name of the first image but with a '1' on the end. Example: 'Photo.jpeg' and 'Photo1.jpeg' would both be in the image view if Photo1.jpeg existed.
Thanks for your help.
I came across a similar task myself once. What I did was, I created a UIScrollView with the frame of the UIImageView and its contentSize would be imageView.frame.size.width * numberOfImages.
let scrollView = UIScrollView(frame: view.bounds)
view.addSubview(scrollView)
scrollView.contentSize = CGSize(width: scrollView.bounds.size.width * CGFloat(numberOfImages), height: scrollView.bounds.size.height))
for i in 0...<numberOfImages.count-1 {
let imageView = UIImageView(frame: CGRect(x: scrollView.bounds.size.width * CGFloat(i), y: scrollView.bounds.origin.y, width: scrollView.bounds.size.width, height: scrollView.bounds.size.height))
imageView.image = UIImage(named: "artwork" + "\(i)")
scrollView.addSubview(imageView)
}
You can animate it to scroll with a Timer if you want.
scrollView.setContentOffset(scrollPoint, animated: true)
you can only show 1 image inside the imageivew at a time, so if you have the lines as follows:
art_image.image = UIImage(named:(artworkPin.title!))
art_image.image = UIImage(named:(artworkPin.title! + "1")?)
art_image would consist only of Photo1 provided such an image exists and that the artworkPin.title unwrapped is also not nil otherwise you could see some different results.
if you do want to add multiple images to an image view for the purpose of animation, you need to use the animationImages property of UIImageView which takes an array of UIImages for example
art_image.animationImages = [UIImage.init(named:"Photo")!,
UIImage.init(named:"Photo1")!]
Hope this helps
EDIT
var imagesListArray = [UIImage]()
for position in 1...5
{
if let image = UIImage.init(named: ("Photo\(position)"))
{
imagesListArray.append(image)
}
}
art_image.animationImages = imagesListArray
art_image.animationDuration = 3.0
art_image.startAnimating()
This would be a safer a way to add the images so it will ONLY add an image if it is not nil and adds Photo1, Photo2 ..... Photo5
With regards to your other questions:
If you want the user to be able to
What do you mean by animation?
I have added two more lines of code, and it gives this result:
art_image.animationDuration = 1.0
art_image.startAnimating()
It will give you something like this:
If you want the user to swipe, then you need to make some changes such as:
using a scrollview, collectionview for example is the easiest or using a gesture recognizer on swipe you need to change the image
EDIT
Have a look at this example. Imagine each button is your annotation so when I tap it, the image changes.
I have 3 images named Photo11.png, Photo21.png and Photo31.png and this is my code inside the button handler
#IBAction func buttonTapped(_ sender: UIButton)
{
if let image = UIImage.init(named: sender.currentTitle!+"1")
{
art_image.image = image
}
}
As you can see I am setting the image with the title of my button + "1" as so it displays either Photo11.png or Photo21.png etc
I understand that the selector method cannot include arguments, but now I'm at a loss as to how I should go about what I want to do.
My objective is to have 5 UI Image Views, each with an image of a star. When the image is tapped, the star should swap images to grey or blue.
My question is, how do I write only one method that handles changing the star image, depending on which star is tapped? Ideally, I would like to send the image as an argument to the method, though I know that is not possible. The only way I can see around this is to write a method for each of the five stars, but as the code would be identical, I feel like there must be a better way.
On View Did Load:
// add tap recognition to rating stars
let tapGestureRecognizerOne = UITapGestureRecognizer(target:self, action:#selector(self.changeStar))
starOneEditImage.userInteractionEnabled = true
starOneEditImage.addGestureRecognizer(tapGestureRecognizerOne)
let tapGestureRecognizerTwo = UITapGestureRecognizer(target:self, action:#selector(self.changeStar))
starTwoEditImage.userInteractionEnabled = true
starTwoEditImage.addGestureRecognizer(tapGestureRecognizerTwo)
let tapGestureRecognizerThree = UITapGestureRecognizer(target:self, action:#selector(self.changeStar))
starThreeEditImage.userInteractionEnabled = true
starThreeEditImage.addGestureRecognizer(tapGestureRecognizerThree)
let tapGestureRecognizerFour = UITapGestureRecognizer(target:self, action:#selector(self.changeStar))
starFourEditImage.userInteractionEnabled = true
starFourEditImage.addGestureRecognizer(tapGestureRecognizerFour)
let tapGestureRecognizerFive = UITapGestureRecognizer(target:self, action:#selector(self.changeStar))
starFiveEditImage.userInteractionEnabled = true
starFiveEditImage.addGestureRecognizer(tapGestureRecognizerFive)
And then a method to call on tap of the image:
func changeStar() {
print ("star tapped")
}
I understand that the selector method cannot include arguments
You understand wrong. The parameter to changeStar is the gesture recognizer. And gesture recognizer has a view, and that's the image view you want!
func changeStar(g:UIGestureRecognizer) {
let v = g.view as! UIImageView
// ...
}
I'm trying to do two things in Swift:
· When the user touches the image, toggle between the filtered, and original images temporarily.
· When the user lifts their finger, toggle back.
But I don't know what functions or modules to use, any suggestions?
I have got a image View and four buttons 「New Photo」,「Filter」,「Compare」,「Share」.
Try this
override func viewDidLoad(){
super.viewDidLoad()
// add Tap gesture recognizer to ImageView
let imageView = self.your_imageView
let tapGestureRecognizer = UILongPressGestureRecognizer(target:self, action:Selector("toggleImage:"))
imageView.userInteractionEnabled = true
imageView.addGestureRecognizer(tapGestureRecognizer)
}
func toggleImage(sender: UILongPressGestureRecognizer){
if sender.state == .Began{
originalImage()
}else if sender.state == .Ended{
filteredImage()
}
}
It uses UILongPressGestureRecognizer()
I would recommend looking into UILongPressGestureRecognizer.
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UILongPressGestureRecognizer_Class/index.html#//apple_ref/occ/instp/UILongPressGestureRecognizer/minimumPressDuration
When the gesture begins, change the UIImage being displayed. You can detect when the gesture ends with UIGestureRecognizerStateEnded. I'm sure you'll figure it out!
I set the minimum press duration to 0.1 from default 0.5 to make it look like a tap button. Code changes to check if the filtered image is not nil and it is not equal to the original image. I set back and forth the image view according the state began and end
override func viewDidLoad() {
super.viewDidLoad()
// adding Tap gesture recognizer to image view
let longPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(imageTapped(_:)))
// Enabling the user interaction for the image view
imageView.userInteractionEnabled = true
imageView.addGestureRecognizer(longPressGestureRecognizer)
// Changing the default minimum press duration from 0.5 to 0.1
longPressGestureRecognizer.minimumPressDuration = 0.1
}
// image tapped function that changes the image view when the user presses on the image view
func imageTapped(longPressGestureRecognizer: UILongPressGestureRecognizer) {
if longPressGestureRecognizer.state == .Began {
imageView.image = originalImage
} else if longPressGestureRecognizer.state == .Ended {
if filteredImage != nil && filteredImage != originalImage {
imageView.image = filteredImage
}
}
}
I'm trying to have the ability to remove the subview the user chooses with three taps.
The problem I'm having is I can only get it to remove in the order the subviews were created. I have played around with 'viewWithTag' but can't figure out how to get it to do what I want.
Can I achieve what I want with the 'tapGesture' removing the subview from the location I tapped?
I'm a noob (as the kids say), so any help is much appreciated!
Thanks!
#IBAction func unwindToParent(segue:UIStoryboardSegue){
var source = segue.sourceViewController as PropViewController
var propImage = UIImage(named: name as String!)
clipView = UIImageView(image: propImage!)
clipView.frame = CGRectMake(0, 0, 200.0, 200.0)
clipView.center = CGPoint (x: view.bounds.size.width/2, y: view.bounds.size.height/2)
clipView.contentMode = UIViewContentMode.ScaleAspectFit
clipView.userInteractionEnabled = true
clipView.multipleTouchEnabled = true
clipView.layer.cornerRadius = 10.0
setTag = tagCounter
tagCounter++
clipView.tag = setTag
addPinchGestureRecognizer(clipView)
addPanGestureRecognizer(clipView)
addRotationGestureRecognizer(clipView)
addTapGestureRecognizer(clipView)
view.addSubview(clipView)
view.bringSubviewToFront(clipView)
let recognizer = UITapGestureRecognizer(target: self, action:Selector("Trash:"))
recognizer.numberOfTapsRequired = 3
recognizer.delegate = self
clipView.addGestureRecognizer(recognizer)
}
func Trash(gesture: UITapGestureRecognizer){
clipView.viewWithTag(setTag)?.removeFromSuperview()
}
The gesture recogniser has a view property - that will be the tapped view.
Never use tags for anything.
Theres probably a half dozen ways I can see this being done.
The 'simplest' is probably getting the location of the tap
tap.locationInSubview
And then checking if any of the views contain that point
uiViewObject.containtsPoint()
If it contains the point remove it
Or you could add gestures to each view and, as suggested by jrturton, uses the taps view source as the view to remove.