How to access camera with swiping gesture?
Where you have:
action: Selector(("handleSwipes"))
put this:
action: #selector(handleSwipes)
The reason is that "handleSwipes"
is not the selector for your handleSwipes
function, and you do not know how to form the selector correctly. But the compiler does know, and using #selector
syntax tells it to do so.
Place Swipe Gesture over UIImagePickerController
Instead of:
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]
initWithTarget:_cameraUI.view
action:@selector(toggleControlsWithGesture)];
do:
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]
initWithTarget:self
action:@selector(toggleControlsWithGesture)];
Explanation:
For your UISwipeGestureRecognizer
object, you are currently doing -initWithTarget:_cameraUI.view
.
This means the target that will respond to the specified action method will be _cameraUI.view
but _cameraUI.view
does not provide any -toggleControlsWithGesture
method and hence the error.
The -toggleControlsWithGesture
method will be found in this class and so you will need to specify the target as self
.
Example: Consider in XYZClass.m, we do something like:
ABCClass *abcObject = [ABCClass alloc] init];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:abcObject
action:@selector(doSomething)];
This basically says that the abcObject
will respond to the event by firing a doSomething
method.
But... for this to happen, ABCClass
should have defined the doSomething
method.
In your case, _cameraUI
is of UIImagePickerController
class and it's view
may be a property or another class object. In either case, it does not have the -toggleControlsWithGesture
method which you created for your purposes.
How to detect swipe gestures on the screen and pass them to a small ViewPager at the bottom?
I got some code from another stackoverflow question about detecting left and right swipe gesture and adapted it to my use case, by adding some more code. Here is the final result:
private GestureDetectorCompat gestureDetector;
public void onCreate(...) {
gestureDetector = new GestureDetectorCompat(this, new GestureListenerImpl());
}
relativeLayout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
gestureDetector.onTouchEvent(event);
return false;
}
});
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
private class GestureListenerImpl extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
if(isRightToLeftSwipe(e1, e2, velocityX)) {
viewPager.setCurrentItem(viewPager.getCurrentItem() + 1);
return false;
} else if (isLeftToRightSwipe(e1, e2, velocityX)) {
viewPager.setCurrentItem(viewPager.getCurrentItem() - 1);
return false;
}
return false;
}
}
private boolean isRightToLeftSwipe(MotionEvent e1, MotionEvent e2, float velocityX) {
return e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE &&
Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY;
}
private boolean isLeftToRightSwipe(MotionEvent e1, MotionEvent e2, float velocityX) {
return e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE &&
Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY;
}
Swipe gesture not being recognised
I just realised that when I set up my view, I set the camera control as such:
gameView.allowsCameraControl = true // Camera control
when it should really be:
gameView.allowsCameraControl = false // Camera control
I assume this is because the camera is overriding the gestures to the view, and I completely forgot about this! Works well as expected now, and hope it helps anyone in the future who also made this same small mistake.
Swipe from left border to open activity
So in case you want to achieve a similar navigation as in Instagram you should note that the navigation/UX is based on a ViewPager
(consisting of fragments
/pages) and the camera fragment will be implemented with its own SurfaceView
(camera). Controlling The Camera and ViewPager documentation from google should be able to make you go forward with it.
Sliding a view in with a touch gesture
The end result was a solution using a viewpager with an adapter that has pages between layouts.
The end pager view looked something similar to:
View (Empty) -> View (Camera Controls)
The view pager is assigned to page one (Camera Controls) and the user can swipe left to get rid of the controls. I used the position given by the Page Transformer to give each element a different 'velocity'.
Objective C: Camera Swipe from user's finger
Basically, you need an initial velocity (measured in points per second, for example) and a deceleration rate (measured in points / second^2). If you use a gesture recognizer to detect a swipe, it will give you the velocity for free. Otherwise you will have to calculate it yourself from the positions and timestamps of the different stages of the swipe.
Now, in your update method, advance your view according to the velocity:
distance travelled = velocity * time
And use the deceleration rate to update the velocity for the next frame:
delta_v = deceleration rate * time // should give a negative value
new velocity = velocity + delta_v
As soon as the velocity drops to a threshold close to 0, stop the motion.
These formulas are for linear movements but even though you are doing a circular motion, I would try experimenting with them. Or you could do the same calculations with angular velocities. Wikipedia probably has the formulas you will have to know.
Related Topics
Open Attachment from Mail Using iOS 8 App [Swift]
In Swift Can You Trap "Fatal Error Unexpectedly Found Nil While Unwrapping an Optional Value"
Include Inheritance Constraint in Swift Generic Types
Msmessagelivelayout Freeze/Crash in Transcript When Info.Plist Contains Privacy Request
Moving from Nsurlconnection to Nsurlsession for Soap Post in Swift
Issues with Uploading from Xcode 9 to App Store/ Itunes Connect
Not Getting Screenlock Notification on Swift 4 on Mac
Verifying The Purchase (Receipt) of Another Application (Mac App Store)
Calling Asynchronous Method Inside For-Loop
Cache That Can Purge Unused Objects by Demand
How to Name File Stored to Files App via Uactivityviewcontroller
How to Set .Realm File on Realm
Preload a Scene to Prevent Lag
Firebase Remove Snapshot Children Swift
Why Can't I Get The Index of a Filtered Realm List