I'm currently working on an AR app and I want to trigger an action (for example a scene change) only when a button was pressed beforehand. Here's the process I'm trying to build:
Object spawns in front of user
User taps on button to select a tool
User taps on the object and the action sequence from the RC project gets triggered
So far I created a the initial loading of the Scene,
guard let anchor = try? Excavation.loadDirtpile() else {
return
}
a variable for the button state
var shovelPressed: Bool = false
And a function that sets the state
#IBAction func shovelButtonPressed(_ sender: Any) {
shovelPressed = true
}
This is my first time working with Swift and Reality Composer so I'm quite confused :D
I hope you can help!
Related
I'm pretty new to XCode UI tests and I'm trying to run a test where I fill two text labels and then I press a button. After the button is pressed the app should make an URL call and be redirected to another view controller. I want to check if at the end of this operation the second view controller is displayed.
To test this, I have written the following test:
let app = XCUIApplication()
app.launch()
let ownerTextField = app.textFields["ownerTextField"]
ownerTextField.tap()
ownerTextField.typeText("UserA")
let repositoryTextField = app.textFields["repositoryTextField"]
repositoryTextField.tap()
repositoryTextField.typeText("AppB")
app.buttons["SearchButton"].tap()
XCTAssertTrue(app.isDisplayingResults)
Where isDisplayingResults is
extension XCUIApplication {
var isDisplayingResults: Bool {
return otherElements["resultView"].exists
}
}
I have set up the identifier of the View controller inside its swift file class:
override func viewDidLoad() {
super.viewDidLoad()
view.accessibilityIdentifier = "resultView"
...
Nonetheless to say, the test fails. How can I get a success?
It's so simple.
If after clicking the URL, Viewcontroller is presenting means your previous VC button doesn't exist on screen.
So Just check for previous VC button exists or not.
If app.buttons["SearchButton"].esists()
{ //write if code
} else {
// Write else code
}
I'm writing an app that send commands to a set top box.
The box can receive two types of commands: push and release.
I can get the button pressed on macOs in swift.
#IBAction func btnPressed(sender: NSButton) { } in which i send the command and the release. For any command such as change channel, mute or other, all works fine.
Instead, for volume up or done, I need, by doing what I do, to click several time to have the volume up or down.
I got the mouse up and down working, detecting where the click happened (inside the NSImageView (if not a button) corresponding to the up and down images) to simulate a long volume up or down press, but I can't get it inside the button pressed method.
is there a way in the 'buttonpressed' method to combine the mouse event in order to simulate a long press while holding the mouse down?
PS: I have googled and searched here also but did not find a hint.
if it can help:
1 subclass the button class to fire the action on mouseDown and mouseUp (the action will be fired twice)
class myButton: NSButton {
override func awakeFromNib() {
super.awakeFromNib()
let maskUp = NSEvent.EventTypeMask.leftMouseUp.rawValue
let maskDown = NSEvent.EventTypeMask.leftMouseDown.rawValue
let mask = Int( maskUp | maskDown ) // cast from UInt
//shortest way for the above:
//let mask = NSEvent.EventTypeMask(arrayLiteral: [.leftMouseUp, .leftMouseDown]).rawValue
self.sendAction(on: NSEvent.EventTypeMask(rawValue: NSEvent.EventTypeMask.RawValue(mask)))
//objC gives: [self.button sendActionOn: NSLeftMouseDownMask | NSLeftMouseUpMask];
}
}
2: in the storyboard, change the class of the NSButton to your class:
3: set the sender of the action to your subclass and check the currentEvent type:
#IBAction func volUpPressed(sender: myButton) {
let currEvent = NSApp.currentEvent
if(currEvent?.type == .leftMouseDown) {
print("volume Up pressed Down")
//... do your stuff here on mouseDown
}
else
if(currEvent?.type == .leftMouseUp) {
print("volume Up pressed Up")
//... do your stuff here on mouseUp
}
}
I want to create a button that, when pressed, toggles to a different format and stays that way, not allowing the user to toggle it back. For example, I am trying to create a button that says "Special 1" then when it is clicked by the user, it toggles to say "USED". When the word "USED" pops up on the UIButton, it stays that way and the user cannot change it back. Please help me out I can't figure this out. I am also open to other ideas to execute this other then a UIButton, for example maybe a UITableView??
What you can do is create a boolean (true or false) variable in your ViewController, and whenever the button is tapped you set this variable so that the tap function associated with the button can be manipulated.
1.) Make an action connection from your ViewController to your code this can be done by clicking the dual view button (the two circles in the top right corner) then holding control and drag your button into your code. :
For more information on connecting views to your code: https://codewithchris.com/9-hooking-it-all-up-swift-iboutlet-properties/
Skip to 6 min for the actual connection.
2.) Now we can just make our boolean variable, and make a basic if statement:
var didClick:Bool = false
#IBAction func touchButton(_ sender: UIButton) {
if !didClick { // If didClick is false
didClick = true // Set it to true
sender.setTitle("USED", for: .normal)
}
}
Note: The sender should be set to UIButton NOT Any
Should look like this:
_ sender: UIButton
If you are using a storyboard you can write this inside the IBAction function:
#IBAction func buttonName(_ sender: UIButton) {
sender.isUserInteractionEnabled = false
// Do whatever you need to do after...
}
sender's type could be UIButton or Any depending on how you made the connection from the storyboard.
Hi I am making a app that basically updates users on what events are going on in the city, I have it hooked up to parse, so i am able to post new events from parse and if a user clicks "go to this event" i receive the user's info in parse, the only problem I am running into is I don't want the user to be able to click the "go to this event" twice. can someone please help me with preventing user from clicking the button twice. when the user click the button first it takes him to "thank you" view controller, and if the user clicks second time i want to basically say "you are already going to this event"
this is what I am doing to get user's info in parse:
/////// GO TO THE EVENT BUTTON
#IBAction func Going(sender: AnyObject) {
let sweet:PFObject = PFObject(className: "Going")
sweet["userprofile"] = PFUser.currentUser()
sweet["first_name"] = PFUser.currentUser()?["first_name"] as? String
sweet["last_name"] = PFUser.currentUser()?["last_name"] as? String
sweet["email"] = PFUser.currentUser()?["email"] as? String
sweet["club"] = club.text
sweet["date"] = date.text
sweet["eventdetails"] = eventdetails.text
I think that it will have to do something with the userprofileID, so that if the same ID click the Button with EVENTDETAILS"------" (because event details would define the events the most i think and would make it unique) to show the view controller "You are already going to this event"
I am using swift 2 Xcode 7
I am new to programming, I hope someone can help
Create an outlet for the button besides the IBAction that you already created
#IBOutlet var login: UIButton! // rename it to whatever you want
#IBAction func Going(sender: AnyObject) {
// For disabling button
self.login.enabled = false // disable it on click of the button.Change it to true for enabling
// Now write your other code below
I'm building some functionality similar to SnapChat. Press and hold on a view, it brings up a movie to play, then returns to the main view controller when the movie finishes (currently working), or when the user picks up their finger (not working. That's what this question is about).
My problem lies in the IBAction, when the video comes up, the UIGestureRecognizerState changes from Began to Cancelled.
I'd like for the state to not change until the user lifts their finger, which should register UIGestureRecognizerState as Ended
Any tips on how to do that would be awesome. Thanks!
class ViewController: UIViewController {
var moviePlayer: MPMoviePlayerViewController!
#IBAction func handleLongPress(recognizer: UILongPressGestureRecognizer) {
println("\(recognizer)")
if recognizer.state == UIGestureRecognizerState.Began {
playVideo()
}
if recognizer.state == UIGestureRecognizerState.Ended {
self.moviePlayer.moviePlayer.stop()
}
}
func videoHasFinishedPlaying(notification: NSNotification){
println("Video finished playing")
}
func playVideo() {
// get path and url of movie
let path = NSBundle.mainBundle().pathForResource("IMG_8602", ofType:"MOV")
let url = NSURL.fileURLWithPath(path!)
moviePlayer = MPMoviePlayerViewController(contentURL: url)
presentMoviePlayerViewControllerAnimated(moviePlayer)
// construct the views
moviePlayer.view.frame = self.view.bounds
self.view.addSubview(moviePlayer.view)
// remove controls at top and bottom of video
moviePlayer.moviePlayer.controlStyle = MPMovieControlStyle.None
NSNotificationCenter.defaultCenter().addObserver(self, selector: "videoHasFinishedPlaying:",
name: MPMoviePlayerPlaybackDidFinishNotification, object: nil)
}
}
Edit: One possible solution
So this was a total fluke, but I figured out how to do this in this context.
I simply removed the line presentMoviePlayerViewControllerAnimated(moviePlayer) from my playVideo function.
Not entirely sure why that worked but it worked for my context.
This is ONE possibility but I'm open to better suggestions.
Add a 'master view' on top of where you need the touch event
Add the gesture recognizer to that view
Handle the logic within the gesture as you are now, but the subview that needs to be added needs to be added below the view thats receiving the touch.
You can now get the .ended state when the user lifts their finger.
Word of caution. If your view has other touch events make sure this 'master view' is not over top of them because it will intercept those events and hog it for its gesture (unless you set it up to recognize them simultaneously). If thats the case, you can make this 'master view' only a small port of the screen where you need to listen for the touch event without interruption