Interaction Design

RSS for tag

Create engaging ways for users to interact with your software.

Posts under Interaction Design tag

9 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Delay between animation and view accepting touch input
Hi! I was trying to add an animation to my SwiftUI view with UIKit, but after the animation runs there's a delay before the view will accept touch interactions. I thought it was because of the frame size of the view controller, but even after fixing that I still get the delay. Could anyone point me to where I might be going wrong, or if maybe using a UIKit modifier for the animation just doesn't work? Any help would be greatly appreciated! UIView: class BounceView: UIView { required init() { super.init(frame: .zero) } func bounceAnimation() { guard let piece = self.subviews.first else { return } UIView.animate(withDuration: 0.7, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0) { piece.frame.origin.x += 10 } } func bounceBack() { guard let piece = self.subviews.first else { return } UIView.animate(withDuration: 0.7, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0) { piece.frame.origin.x -= 10 } } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } UIView controller: class BounceViewController: UIViewController { init(controller: UIViewController) { super.init(nibName: nil, bundle: nil) view = BounceView() addChild(controller) controller.view.translatesAutoresizingMaskIntoConstraints = false controller.view.backgroundColor = .clear view.addSubview(controller.view) controller.didMove(toParent: self) } // adjusts view to match bounds of child override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() let subviewFrame = self.view.subviews.first?.bounds ?? .zero view.frame = subviewFrame print(subviewFrame) self.updateViewConstraints() } func update(animated: Bool) { let bounceView = view as? BounceView if animated { bounceView?.bounceAnimation() } else { bounceView?.bounceBack() } } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } SwiftUI wrapper: struct BounceUIViewController: UIViewControllerRepresentable { private var controller: UIViewController @Binding var animated: Bool init(controller: UIViewController, animated: Binding<Bool>) { self.controller = controller self._animated = animated } func makeUIViewController(context: Context) -> BounceViewController { BounceViewController(controller: controller) } func updateUIViewController(_ uiViewController: BounceViewController, context: Context) { uiViewController.update(animated: animated) } } View extension: extension View { func bounce(animated: Binding<Bool>) -> some View { modifier(Bounce(animated: animated)) } } struct Bounce: ViewModifier { @Binding var animated: Bool init(animated: Binding<Bool>) { self._animated = animated } func body(content: Content) -> some View { BounceUIViewController(controller: content.uiViewController, animated: $animated) } }
1
0
203
2w
In-app payment via bottom-up swipe gesture
This question came up, a customer wants to add payment, with gesture, to their app. This gesture is a swipe, from bottom to top (like when minimizing applications). The question immediately arose, will the application pass the review with such UI/UX ? Will there be any problems ? I'm not talking about problems when the user can minimize the application when paying, or pay (accidentally) when minimizing. I want to know if there will be any problems from Apple's rules when releasing the app ? I haven't found the exact information yet
1
0
210
Nov ’24
Sign in With Apple works, but blocks app afterwards
This is a continuation of https://developer.apple.com/forums/thread/760861 Still a mixed Qt/C++/ObjC app, developed with Qt Creator. The gist ist that I can call Sign in With Apple and authorise, but once the Authorisation Window/Panel goes away, the app is blocked. PBSigninWithApple:: PBSigninWithApple() { myImpl = [[PBSigninWithApple alloc] initWithOwner:this]; } - (id)initWithOwner:(PBSigninWithApple *) owner { self = [super init]; myOwnerSIWA = owner; ASAuthorizationAppleIDProvider *appleIDProvider = [ASAuthorizationAppleIDProvider new]; ASAuthorizationAppleIDRequest *request = appleIDProvider.createRequest; request.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail]; ASAuthorizationController *controller = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]]; controller.presentationContextProvider = self; controller.delegate = self; [controller performRequests]; return self; } The code example above is obviously reduced, but the real things works. I get the Sign in With Apple window and can authorise by TouchId. The didCompleteWithAuthorization and didCompleteWithError methods also work, emitting the the idendityToken to the calling superclass works, the authorisation window goes away - but not really. The calling QT app is semi-blocked. I can close windows ny using the Escape key, but any clicking just gives the dreaded beep and nothing happens. So I assume that we didn‘t tear down everything and that the anchor or whatever still has to focus. - (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(macos(10.15)) { if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) { ASAuthorizationAppleIDCredential *appleIDCredential = authorization.credential; NSString *user = appleIDCredential.user; NSData *identityToken = appleIDCredential.identityToken; NSData *authorizationCode = appleIDCredential.authorizationCode; emit myOwnerSIWA-&gt;accessCodeReceived(identityToken); } [[NSNotificationCenter defaultCenter] removeObserver:self name:ASAuthorizationAppleIDProviderCredentialRevokedNotification object:nil]; [myAnker close]; [self release]; } - (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(ASAuthorization *)authorization API_AVAILABLE(macos(10.15)) { emit myOwnerSIWA-&gt;accessCodeReceived(QString("")); [[NSNotificationCenter defaultCenter] removeObserver:self name:ASAuthorizationAppleIDProviderCredentialRevokedNotification object:nil]; } -(ASPresentationAnchor)presentationAnchorForAuthorizationController:(ASAuthorizationController *)controller API_AVAILABLE(macos(10.15)) { NSRect frame = NSMakeRect(30, 30, 230, 230); NSUInteger windowStyle = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable | NSWindowStyleMaskFullSizeContentView; NSWindow* window = [[[NSWindow alloc] initWithContentRect:frame styleMask:windowStyle backing:NSBackingStoreBuffered defer:NO] autorelease]; window.minSize = CGSizeMake(200, 100); window.releasedWhenClosed = TRUE; myAnker = window; return window; }
1
0
382
Sep ’24
Passing touches from UIView to a child view?
I made an extension with a UIView that takes a SwiftUI view, gets its UIView, and then adds it as a subview. But now the subview isn't receiving any touches and idk how to fix that. I've already tried point(inside:with:) but it doesn't seem to work. I've also tried forwarding the touches from touchesBegan, touchesMoved, etc., but that didn't work either. Any help or advice would be greatly appreciated! Extension with the UIView: // Add view modifier to View extension View { func transformable() -> some View { modifier(Transformable()) } } // View modifier struct Transformable: ViewModifier { func body(content: Content) -> some View { TransformableUIView(content: content) } } // Wrap UIView struct TransformableUIView<V>: UIViewRepresentable where V: View { private var content: V init(content: V) { self.content = content } func makeUIView(context: Context) -> TransformableView<V> { TransformableView(content: content) } func updateUIView(_ uiView: TransformableView<V>, context: Context) {} } // View that handles zoom, pan, and rotate gestures class TransformableView<V>: UIView, UIGestureRecognizerDelegate where V: View { private var content: V private var initialCenter: CGPoint = .zero private var totalScale: CGFloat = 1.0 private var boundsDidSet = false required init(content: V) { self.content = content super.init(frame: .zero) self.addSubview(content.uiView) let panGesture = UIPanGestureRecognizer(target: self, action: #selector(panPiece(_:))) panGesture.minimumNumberOfTouches = 2 panGesture.maximumNumberOfTouches = 2 panGesture.delegate = self self.addGestureRecognizer(panGesture) let scaleGesture = UIPinchGestureRecognizer(target: self, action: #selector(scalePiece(_:))) scaleGesture.delegate = self self.addGestureRecognizer(scaleGesture) let rotateGesture = UIRotationGestureRecognizer(target: self, action: #selector(rotatePiece(_:))) rotateGesture.delegate = self self.addGestureRecognizer(rotateGesture) } // Position content in center of view override func layoutSubviews() { super.layoutSubviews() // Return if bounds are already set if boundsDidSet { return } guard let piece = self.subviews.first else { return } piece.center = CGPoint(x: self.bounds.size.width / 2, y: self.bounds.size.height / 2) boundsDidSet = true } // Function called when pan gesture is recognized @objc private func panPiece(_ gestureRecognizer: UIPanGestureRecognizer) { guard let piece = gestureRecognizer.view?.subviews.first else { return } // Get the changes in the X and Y directions relative to // the superview's coordinate space. let translation = gestureRecognizer.translation(in: piece.superview) if gestureRecognizer.state == .began { // Save the view's original position. self.initialCenter = piece.center } // Update the position for the .began, .changed, and .ended states if gestureRecognizer.state != .cancelled { // Add the X and Y translation to the view's original position. var newCenter = CGPoint(x: initialCenter.x + translation.x, y: initialCenter.y + translation.y) // Prevent content from leaving view newCenter.x = clamp(value: newCenter.x, min: 0, max: self.bounds.width) newCenter.y = clamp(value: newCenter.y, min: 0, max: self.bounds.height) piece.center = newCenter } else { // On cancellation, return the piece to its original location. piece.center = initialCenter } } // Function called when scale gesture is recognized @objc private func scalePiece(_ gestureRecognizer : UIPinchGestureRecognizer) { guard let piece = gestureRecognizer.view?.subviews.first else { return } if gestureRecognizer.state == .began || gestureRecognizer.state == .changed { // Set min/max zoom let newScale = clamp(value: totalScale * gestureRecognizer.scale, min: 0.2, max: 20) / totalScale piece.transform = (piece.transform.scaledBy(x: newScale, y: newScale)) gestureRecognizer.scale = 1.0 totalScale *= newScale } } // Function called when rotate gesture is recognized @objc private func rotatePiece(_ gestureRecognizer : UIRotationGestureRecognizer) { guard let piece = gestureRecognizer.view?.subviews.first else { return } if gestureRecognizer.state == .began || gestureRecognizer.state == .changed { piece.transform = piece.transform.rotated(by: gestureRecognizer.rotation) gestureRecognizer.rotation = 0 } } func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { return true } func clamp(value: CGFloat, min: CGFloat, max: CGFloat) -> CGFloat { if value < min { return min } else if value > max { return max } else { return value } } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } Get UIView from SwiftUI View: // Get UIView from SwiftUI View extension View { var uiView: UIView { UIHostingController(rootView: self).view } } ContentView: struct ContentView: View { var body: some View { CanvasView() .frame(width: 880, height: 608) .transformable() .background(Color.blue) } }
1
0
637
Jul ’24
What is the secret to good UI?
Hello, I’m an aspiring full stack dev and I’m just wondering how the heck you get good UI AND UX. I’m currently moodboarding and seeing how things look in FigJam and then taking that and coding in Swift. I am struggling and my sanity is hanging on by a string 😂. So tell me, how do you get good UI and UX?
2
1
658
Jul ’24
Zoom in
Hii apple! What about zooming with 2 fingers without making a screenshot to zoom it!! I will love to make a pattent about it!!! Everywhere we ad on the iphone should we zoom in with 2 fingers!!! love to hear from ya
1
0
603
Jun ’24
How to interact during the Transition process?(wwdc24 UIKit consultation)
Recently I tried to apply a custom transition to a custom contextMenu. However, I want to make sure that during the transition process (which is not over yet), my contextMenu elements such as buttons can be tapped. But I tried a lot of things without success. I know you have a lot of experience, so I would like to ask you about how to implement the transition and be able to interact before it is over. I know that a UIView can be tapped during animation, but I haven't tried the button in a UIView. I've been trying to transition ViewControllers. For example, in a transition from fromViewController to toViewController, I wanted to be able to tap on a tableView in toViewController during the transition, but I was frustrated and found it very difficult to implement. I would like to ask you about the possibilities of interaction during the Viewcontrollers transition. (PS: In Github Issues, I uploaded a GIF example of the plus button on the left of the input box in iMessage. After tapping the plus button, you can tap the "Apple Cash" button before the transition is finished.) Your advice would be incredibly valuable to me. Thank you in advance for your time and assistance. [GithubLink]https://github.com/Juhnkerg/DemoForInteractionDuringTransition)
0
1
528
Jun ’24
4.3.0 Design Spam
Hello, I've a team for developing game in my small company. And we've developed an Obstacle game in Unity from scratch. every single UI, logic & even sound is implemented by our own developers and musicians. It means, every single element is proprietory of our own. I suggest you folks to try out the game in Android playstore by searching the game name as "Cherry Blossom Hills Obstacle" . But once I submitted the same game in iOS App store, the reviewers continously saying, it's a 4.3.0 Design Spam without any to the point feedback basically :( Could you anyone help me resolving this issue? A definitive but even single help/suggestion would be highly appreciated. Regards, Md. Rezoanul Alam.
1
0
995
Feb ’24