Post

Replies

Boosts

Views

Activity

Reply to How to ensure only one player sets game options in a match
I am planning on using a "player attribute mask" as part of the match request to indicate I am a "host". The match would then find other players who are not hosts to join into my game. I hope this sounds correct.Of course, being a host would allow myself to set up the game options before I send out the match request. Other players would start my application and select "Join a Game", which would mean they do not want to be a host and would not be offered the opportunity to set up game otions. They would just wait for Game Center to place them into a game only as a non-host
Dec ’19
Reply to How can the application know it was started as a result of a Game Center Invite request?
Thanks for pointing out the clash which can occur if two players are setting up a match at the same time. Two players might be requesting each other to join into a new match request at the same time OR the invited player might be setting up a match which does not include the player who is sending the invite request. I will need to think about these two scenarios after I get a basic match set up and working orf course.I have never been invited into a game center game before so cannot understand what an "invited player" actually sees on their screen. I assume the invited player would just have to accept/decline a "Do you want to play?" question from Game Center. If they accept the game then the folwing would occur .... but perhaps you can confirm? 1) The didAcceptInvite method would be called on the device of the invited player only func player(_ player: GKPlayer, didAccept invite: GKInvite)2) inside the didAcceptInvite method there would be a call to the following method so the invited player can create the "match" (based on the data in the invitation) on their device: func match(for invite: GKInvite, completionHandler: ((GKMatch?, Error?) -> Void)? = nil)3) The following method would be called on the device of the player who is sent the invite so they know the invited player accepted (ie: connected) the match invitation: func match(_ match: GKMatch, player: GKPlayer, didChange state: GKPlayerConnectionState)Question:Why do you need to present a "new GKMatchmakerViewController" to the invited player in the didAcceptInvite method? We do not want the invited player to start selecting friends and setting up a match themselves so I am confused what the view controller provides to the invited player
Dec ’19
Reply to Invite players programmatically into a match
>>What is wrong with the Game Center View Controllers?I want to be able to invite my friends to the match and if they cannot join then be able to invite random players into the match at that point to fill the available slots. I do not think Game Center view controller provides this type of thing since I call the findMatchWithMinPlayers method which then brings up the Game Center viewcontroller with all random players.I discovered I can provide a "matchRequest.recipients" array indicating specific players to invite (like my friends), but I am not sure whether the Game Center UI view controller will default to inviting a random player automatically if one of my friends declines the invitation. Do you know how Game Center UI view controller handles a decline of a player listed in the "recipient" array?
Dec ’19
Reply to Invite players programmatically into a match
PBK,Thanks for the code, but I have all of this code already working.I would like to find a way to Invite players to participate in a match without presenting the Game Center matchmaker view controller and having to click an "Invite Players" button. I would like to design my own view controller interface to add players to a game instead of using the default Game Center matchmaker view controller.I am assuming I would still need to create the match using the GKMatchRequest (as below) but I am hoping I do not have to display the matchmaker view controller which is provided. let request = GKMatchRequest.init() request.minPlayers = minPlayers request.maxPlayers = maxPlayersI have googled and googled but have not found anythingDo you know how to do this?
Dec ’19
Reply to viewWillLayoutSubviews messing with my animation
Now that I am using the leading constraint value for positioning of the dataView (instead of setting origin.x) then the animation works properly. However, I just realized that setting the constraint off the screen (line 9) before animation starts, results in an "Unable to simultaneously satisfy constraints" warning being generated in the debugger console area. I receive the same warning again when line 36 occurs when closing the dataView as well.Since I am resetting the constraint to be off the screen (line 9), in preparation for the "open" animation, I am assuming the trailing constraint no longer can be satisifed so this is what is causing the warning. I am not sure how to resolve this warning though. If I disable the trailing constraint then I think all of constraints for all the views (buttons, labels, etc..) which are inside dataView "view" will now have constraint issues since they all depend on dataView constraints being correct (blue lines).Any idea how to address this debugger constraint warning?
Dec ’19
Reply to viewWillLayoutSubviews messing with my animation
I assume you mean the issue is that animation must use constaints to ensure all subviews are animated as well. Since I was simply changing the origin.x value for dataView (and not the constraint value) then the animation logic could not figure out how to move (animate) the dataView properly since the new origin.x value and the existing fixed constraint vlaue were conflicting. Anyway, I thought constraint settings were only applied when the orientation changed and this was a wrong assumption of mine.Thanks for all your help Claude !
Dec ’19
Reply to viewWillLayoutSubviews messing with my animation
*** I FOUND A SOLUTION THAT WORKS !!! ***I continued to google around and found a couple of posts.The first post indicated that if you have a constraint assigned to a view, that you want to animate, then you should be animating the view by changing the constraint values instead of the origin.x or origin.y values.As a result I decided the create an IBOutlet for the leading constraint to the dataView (ie: viewLeadingAlignment_Constraint) and set it accordingly inside the openView and closeView functions. I guess since I am now using a "constraint value" for animation, then when the viewWillLayoutSubview( ) call occurs, while animation is active, then the view still maintains it's current constraint value location and no longer gets reset back to the 16 constraint I had before.Anyway, I ran the program and the dataView appears and disappears without any animation at all, so this did NOT work.However, please read more below ...The second post indicated the following "Two important notes":You need to call layoutIfNeeded within the animation block. Apple actually recommends you call it once before the animation block to ensure that all pending layout operations have been completedYou need to call it specifically on the parent view (e.g. self.view), not the child view that has the constraints attached to it. Doing so will update all constrained views, including animating other views that might be constrained to the view that you changed the constraint of (e.g. View B is attached to the bottom of View A and you just changed View A's top offset and you want View B to animate with it)Based on these two notes, I added calls to self.view.layoutIfNeeded( ) after each line where I set the IBOutlet constraint value inside the openView and closeView functions and then everything worked as desired (see updated/working code below). I can now open/close the dataView in portrait and landscape modes with expected animation. override func viewDidLoad() { dataView.isHidden = true } @IBAction func openView() { //ensure view is out of the viewing area viewLeadingAlignment_Constraint.constant = getScreenSize().width + 100 self.view.layoutIfNeeded() //make view visible for eventual animation dataView.isHidden = false //animate view appearing UIView.animate(withDuration: 1.0, delay: 0, options: .curveEaseInOut, animations: { self.viewLeadingAlignment_Constraint.constant = 16 self.view.layoutIfNeeded() }, completion: nil ) } @IBAction func closeView() { //animate view disappearing UIView.animate(withDuration: 1.0, delay: 0, options: .curveEaseInOut, animations: { //move view out of the viewing area self.viewLeadingAlignment_Constraint.constant = self.getScreenSize().width + 100 self.view.layoutIfNeeded() }, completion: { [weak self] finished in //hide view self?.dataView.isHidden = true }) }Based on the second posting #2 statement, perhaps my original design of moving dataView by changing the origin.x value was not working properly since the dataView "view" included other views (buttons, labels, etc..) inside of it. I was requesting animation to occur on dataView only, so the other views, which are located inside of dataView, were not part of this animation request and thus bad/weird things happened during animation, however, this is just a complete guess.
Dec ’19
Reply to viewWillLayoutSubviews messing with my animation
>>Maybe. But why never a problem with open ?Exactly. This is all weird stuff. The problem is, I am not sure what other debug statements or code logic to try out to keep debugging this issue. I am at a lost of what else to try to narrow the issue down.>>Did you try to delay the animation by 1 second (to leave plenty of time to complete) I set the closeView( ) function animation to be 5 seconds in an attempt to really slow it down so I can look for any weird display issues, but I did not notice anything different. The dataView always comes in from the left (negative location) and stops at 16 when the issue happens.
Dec ’19
Reply to viewWillLayoutSubviews messing with my animation
>>How does it display exactly ? What is this wrong place ?The proper desired behavior is as follows:1) Clicking openButton should animate dataView coming into the display starting from the right side at origin.x = 767 and moving to origin.x = 162) Clicking closeButton should animate dataView moving out of the display, starting from current position origin.x =16 and moving out/off the right side of the screen to origin.x = 767What is actually happening is as follows:1) Clicking openButton animates dataView coming into the display starting from the right side at origin.x = 767 and moving to origin.x = 16(this IS proper behavior and is good! )2) Clicking closeButton animates dataView moving into the display, starting from origin.x = -767 and moving to origin.x =16(this IS NOT proper behavior and is bad)>>As I cannot test your project, could you try different animation for close (-100 vs +100) so that view does not completely disappearhehe, I also tried this myself while trying to find an answer, but just tried it again to confirm results for you once again.Results using 200- dataView starts off as hidden (of course)- I click the openButton and the openView( ) function is called which hardcodes the origin.x = 200- openView( ) function then makes the dataVIew visible (isHidden = false) and I see the dataView display at origin.x = 200- UIView.animate( ) is called to move the dataView from current position (origin.x = 200) to new position (origin.x = 16) to animate the view moving from right to left from 200 to 16.- I see the dataView move right to left from 200 to 16 as desired.- I click the closeButton and the closeView( ) function is called- closeView( ) function prints the "origin.x" value as 16, which is correct since this is where the current dataView is positioned- UIView.animate( ) is called to move the dataView from current position (origin.x = 16) to new hardcoded position (origin.x = 200) to animate the view moving from left to right from 16 to 200- I see the dataVIew move left to right from -200(negative) to 16, which is not correct.Of course viewWillLayoutSubviews( ) is called right after closeView( ) function is entered and while UIView.animate( ) call is active (ie: completion closure has not yet been called). This changes the origin.x value back to the leading constraint setting value of 16 while animation is still active. I can only assume changing the origin.x value while the animation is active, which uses the origin.x value, is somehow confusing the animation process, however, this is a guess of course as I do not understand how UIView.animate( ) behaves when the origin.x value changes while animation, which is using origin.x, is still active.
Dec ’19
Reply to viewWillLayoutSubviews messing with my animation
hardcoding to -767 results:When I switch from portrait mode into landscape mode and then click the openButton, I see the dataView window animate into view from the LEFT side now. It seems like it is moving from origin.x = -767 to origin.x = 16 as we would expect now.When I then click the closeButton, I see the dataView window move in from the RIGHT side and stop animating when it hits origin.x = 16. It seems to be animating from positive(+) origin.x = 767 back to origin.x = 16 (ie: moving right to left). The viewWillLayoutSubviews( ) function is called (as always) right after entering the closeView( ) function occurs. This results in the -767 being switched to 16 since the dataView snaps back to it's leading constraint setting value of 16.This handling is pretty much the opposite of what is going on when it is hardcoded to positive 767The issue still seems to me that viewWillLayoutSubviews( ) is messing up the animation since it occurs while animation is already activeIt is all very weird stuff.
Dec ’19
Reply to viewWillLayoutSubviews messing with my animation
>>What do you get as print ? Are they the correct value (post rotation I mean) Debug "print" statement outputWhen I switch from portrait mode into landscape mode and then click the openButton, I see the following debug: <Note: OPEN button clicked here> openScoreWindow -- enter dataView.frame.origin.x = 16.0 <--- this value is expected since dataView is currently hidden, but is located at origin.x = 16 when openView( ) function is first called. In the openView( ) function, I then hardcode "origin.x = 767" before the call to UIView.animate( ) occurs animation complete - openScoreWindow <Note: CLOSE button clicked here> viewWillLayoutSubviews dataView.frame.origin.x = 16.0 viewDidLayoutSubviews dataView.frame.origin.x = 16.0 closeScoreWindow -- enter dataView.frame.origin.x = 16.0 <--- this is the expected value since origin.x should be 16 when dataView is currently opened viewWillLayoutSubviews <--- this routine is called by the system which seems to be messing up my animation request dataView.frame.origin.x = 767.0 <--- this value was hardcoded in the closeView( ) function inside UIVIew.animate( ) since I want my origin.x to move from 16(current) to 767 when closing the dataView, so this is good. viewDidLayoutSubviews dataView.frame.origin.x = 16.0 <--- this proves the "leading" constraint is reset automatically back to 16 during active animation animation complete - closeScoreWindow . <-- this is when animation has completed>> ... between open and close you refer to self.getScreenSize. Is it already updated when you call ?I decided to hardcode line 17 and line 49 to have "origin.x = 767", which removes the calls to getScreenSize() completely. The issue still occurs in landscape mode.>>Could you try adding a needsLayout() at the very beginning of closeView().I actually tried this myself already, but just tried all of the following again just now:- I added a call to self.view.setNeedsLayout( ) at line 5 (see below) only and the issue still occurred.- I removed line 5 and added line 13 only and the issue still occurred.- I added line 5 and line 13 at the same time and the issue still occurred- Keeping line 5 and line 13, I then added calls to self.view/layoutIfNeeded( ) at line 6 and line 14 to force a call to viewWillLayoutSubviews( ) to occur. The viewWillLayoutSubviews( ) call does occur two times (as expected) but the issue still occurs@IBAction func closeView() { print("closeScoreWindow -- enter") print(" dataView.frame.origin.x = \(dataView.frame.origin.x)") self.view.setNeedsLayout() self.view.layoutIfNeeded() //animate view moving from left to right off the screen UIView.animate(withDuration: 3.0, //1 second delay: 0, options: .curveEaseInOut, animations: { self.view.setNeedsLayout() self.view.layoutIfNeeded() //move view out of the viewing area self.dataView.frame.origin.x = self.getScreenSize().width + 100 }, completion: { [weak self] finished in //hide the view self?.dataView.isHidden = true print(" animation complete - closeScoreWindow") print("") }) }What I see visually when the issue occursWhen I switch from portrait mode into landscape mode and then click the openButton, I see the dataView window animate into view from the right side, moving from "origin.x = 767" to "origin.x = 16" as desired.When I now click the closeButton, I print the origin.x value and confirm it has an expected value of 16. A call to UIView.animate( ) is then made, requesting animation of dataView to occur from the current origin.x = 16 position to a final position of origin.x = 767 and then the animation begins. However, the dataView "view" disappears from the display screen (which is wrong) and then animates back into the display area from the "left" side of the screen (which is wrong) and then stops animating when dataView reaches origin.x = 16 (which is wrong).Visually it looks to me that the animation is moving dataView from -767 (negative) to 16 when the issue occurs, however, I cannot prove this since I never see a "print" debug statement showing me origin.x moves to a negative number. However, this is exactly what it looks like viewing the display when the issue occurs
Dec ’19