Posts

Post marked as solved
2 Replies
1.1k Views
I am creating an SKScene with two buttons.import UIKit import SpriteKit class IntroScene: SKScene { override func didMove(to view: SKView) { // BUTTON PLAY GAME let btnPlay = BtnPlay(normalTexture: defaultBtnTexture, selectedTexture: selectedBtnTexture, disabledTexture: nil) btnPlay.size = CGSize(width: 250, height: 75) btnPlay.position = CGPoint(x: frame.midX,y: frame.height/3*1) btnPlay.name = "btnPlay" btnPlay.setButtonAction(target: self, triggerEvent: .TouchUpInside, action: #selector(IntroScene.goToGameScene)) print("BUTTON PLAY FRAME 1 ",btnPlay.frame) addChild(btnPlay) // BUTTON 'FIND PLAYERS' let btnFindPlayers = BtnFindPlayers(normalTexture: defaultBtnTexture, selectedTexture: selectedBtnTexture, disabledTexture: nil) btnFindPlayers.size = CGSize(width: 250, height: 75) btnFindPlayers.position = CGPoint(x: self.frame.midX,y: self.frame.height/3*2) btnFindPlayers.name = "btnFindPlayers" btnFindPlayers.setButtonAction(target: self, triggerEvent: .TouchUpInside, action: #selector(IntroScene.goToConnectVC)) print("BUTTON FIND FRAME 1 ",btnFindPlayers.frame) addChild(btnFindPlayers) } @objc func goToGameScene() { print("Go to Game Scene") } @objc func goToConnectVC() { print("Go to Connect VC") } }This is the custom class for one of the buttons. The other class uses similar methods:import SpriteKit class BtnPlay: SKSpriteNode { enum BtnPlayType: Int { case TouchUpInside = 1,TouchDown, TouchUp } var disabledTexture: SKTexture? var defaultTexture: SKTexture var selectedTexture: SKTexture var label: SKLabelNode var isEnabled: Bool = true { didSet { if disabledTexture != nil { texture = isEnabled ? defaultTexture : disabledTexture } } } var isSelected: Bool = false { didSet { texture = isSelected ? selectedTexture : defaultTexture } } required init(coder: NSCoder) { fatalError("NSCoding not supported") } init(normalTexture defaultTexture: SKTexture!, selectedTexture:SKTexture!, disabledTexture: SKTexture?) { self.defaultTexture = defaultTexture self.selectedTexture = selectedTexture self.disabledTexture = disabledTexture self.label = SKLabelNode(fontNamed: "Helvetica"); self.label.text = "PLAY" super.init(texture: defaultTexture, color: UIColor.white, size: defaultTexture.size()) isUserInteractionEnabled = true self.label.verticalAlignmentMode = SKLabelVerticalAlignmentMode.center; self.label.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.center; addChild(self.label) let bugFixLayerNode = SKSpriteNode(texture: nil, color: UIColor.clear, size: defaultTexture.size()) bugFixLayerNode.position = self.position addChild(bugFixLayerNode) } var actionTouchUpInside: Selector? var actionTouchUp: Selector? var actionTouchDown: Selector? weak var targetTouchUpInside: AnyObject? weak var targetTouchUp: AnyObject? weak var targetTouchDown: AnyObject? func setButtonAction(target: AnyObject, triggerEvent event:BtnPlayType, action:Selector) { switch (event) { case .TouchUpInside: targetTouchUpInside = target actionTouchUpInside = action case .TouchDown: targetTouchDown = target actionTouchDown = action case .TouchUp: targetTouchUp = target actionTouchUp = action } } func setButtonLabel(title: NSString, font: String, fontSize: CGFloat) { self.label.text = title as String self.label.fontSize = fontSize self.label.fontName = font } override func touchesBegan(_ touches: Set, with event: UIEvent?) { if !isEnabled { return } isSelected = true if (targetTouchDown != nil && targetTouchDown!.responds(to: actionTouchDown)) { UIApplication.shared.sendAction(actionTouchDown!, to: targetTouchDown, from: self, for: nil) } } override func touchesMoved(_ touches: Set, with event: UIEvent?) { if !isEnabled { return } let touch: AnyObject! = touches.first let touchLocation = touch.location(in: parent!) if (frame.contains(touchLocation)) { isSelected = true } else { isSelected = false } } override func touchesEnded(_ touches: Set, with event: UIEvent?) { if !isEnabled { return } isSelected = false if (targetTouchUpInside != nil && targetTouchUpInside!.responds(to: actionTouchUpInside!)) { let touch: AnyObject! = touches.first let touchLocation = touch.location(in: parent!) if (frame.contains(touchLocation)) { UIApplication.shared.sendAction(actionTouchUpInside!, to: targetTouchUpInside, from: self, for: nil) } print("BUTTON PLAY FRAME ",frame) print("BUTTON PLAY TOUCHES ",touchLocation) } if (targetTouchUp != nil && targetTouchUp!.responds(to: actionTouchUp!)) { UIApplication.shared.sendAction(actionTouchUp!, to: targetTouchUp, from: self, for: nil) } } }The scene and the buttons are created just fine. Button "Find Players" is created on top. The problem is that when I tap on the lower button ("Play"), nothing happens. The culprit is tapping on the screen. Whenever I tap somewhere on the screen, except for the lowest part of it, the upper button gets selected. So, if I tap on the lower button, I still see on the console:BUTTON FIND FRAME (387.0, 474.5, 250.0, 75.0) BUTTON FIND TOUCHES (409.139404296875, 563.622131347656)Looks like the frame of the upper button is much greater than the button itself and superimposes the lower button not letting me tap on it.Have no idea why this is happening.I would greatly appreciate if someone can help.
Posted
by igorland.
Last updated
.
Post marked as solved
2 Replies
1.1k Views
Hi. I am using Swift's Multipeer Connectivity framework to try to pass data from SKScene:My AppDelegate class:class AppDelegate: UIResponder, UIApplicationDelegate { /// Object to class ConnectionManager var connectionManager: ConnectionManager! var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch connectionManager = ConnectionManager() return true } }This is a subclass of SKScene:class GameScene: SKScene { /// Object of appDelegate let appDelegate = UIApplication.shared.delegate as! AppDelegate override func touchesEnded(_ touches: Set, with event: UIEvent?) { for touch in touches { let location = touch.location(in: self) if let card = atPoint(location) as? Card { // Code to manipulate SKNodes } print("TOUCHES ENDED") // Send Data to Peers appDelegate.connectionManager.sendDataToPeer() } } }This is the class that manages MPC connectionclass ConnectionManager : NSObject, MCSessionDelegate, MCNearbyServiceBrowserDelegate, MCNearbyServiceAdvertiserDelegate, StreamDelegate { var delegate: ConnectionManagerDelegate? override init() { super.init() // Initialize peerID peer = MCPeerID(displayName: UIDevice.current.name) // Session object session = MCSession(peer: peer, securityIdentity: nil, encryptionPreference: MCEncryptionPreference.optional) session.delegate = self // Browser object browser = MCNearbyServiceBrowser(peer: peer, serviceType: CONNECTION_SERVICE_TYPE) browser.delegate = self // Advertiser object advertiser = MCNearbyServiceAdvertiser(peer: peer, discoveryInfo: nil, serviceType: CONNECTION_SERVICE_TYPE) advertiser.delegate = self } /** State of the session */ func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) { switch state { case MCSessionState.connected: print("Connected to session: \(session)") delegate?.connectedWithPeer(peerID: peerID) // Start Stream startSession(peer: peerID) case MCSessionState.connecting: print("Connecting to session: \(session)") default: print("Did not connect to session: \(session)") stopSession() } } /** Starting session */ func startSession(peer peerID: MCPeerID) { print("STARTING STREAM IN SESSION...") do { try outputStream = self.session.startStream(withName: "stream", toPeer: peerID) print("OUTPUT STREAM IN STARTSESSION? ",outputStream) if let outputStream = outputStream { outputStream.delegate = self outputStream.schedule(in: RunLoop.main, forMode:RunLoopMode.defaultRunLoopMode) outputStream.open() print("STREAM WITH PEER OPENED: ",peerID) } } catch let error { print("ERROR STARTING STREAM IN SESSION: \(error)") } } /** Sending data to peer */ func sendDataToPeer() { if session.connectedPeers.count > 0 { print("SEND DATA TO PEER: MORE THAN ONE PEER") let message = "This is a string test" let data = NSKeyedArchiver.archivedData(withRootObject: message) if let outputStream = outputStream { _ = data.withUnsafeBytes { outputStream.write($0, maxLength: data.count) } print("OUTPUTSTREAM FROM SENDING DATA TO PEER") } } } /** Receiving stream data */ func session(_ session: MCSession, didReceive stream: InputStream, withName streamName: String, fromPeer peerID: MCPeerID) { if streamName == "stream" { stream.delegate = self stream.schedule(in: RunLoop.main, forMode: RunLoopMode.defaultRunLoopMode) stream.open() print("STREAM OPENED: ",streamName) } } func stream(aStream: Stream, handleEvent eventCode: Stream.Event) { switch(eventCode) { case Stream.Event.hasBytesAvailable: print("--STREAM EVENT HAS BYTES--") let input = aStream as! InputStream var buffer = [UInt8](repeating: 0, count: 1024) //allocate a buffer. The size of the buffer will depended on the size of the data you are sending. let numberBytes = input.read(&buffer, maxLength:1024) let dataString = NSData(bytes: &buffer, length: numberBytes) let message = NSKeyedUnarchiver.unarchiveObject(with: dataString as Data) as! String //deserializing the NSData print("STREAM: ",message) case Stream.Event.hasSpaceAvailable: print("--STREAM EVENT HAS SPACE AVAILABLE--") break default: print("--STREAM EVENT DEFAULT--") break } } }So, I have no issues with connection, browsing or advertising. I see that I am connected to the session, then I see: STREAM WITH PEER OPENED... STREAM OPENED. When I manipulate with the SKNodes, I also see: "OUTPUTSTREAM FROM SENDING DATA TO PEER". So, data is being sent and the InputStream is supposedly opened.However, I do not see anything happening in stream(aStream:, handleEvent eventCode:). Looks like there is no data transferred in the stream.I would appreciate if someone could help. Thanks!
Posted
by igorland.
Last updated
.
Post not yet marked as solved
0 Replies
461 Views
Hello.I have written an application in Java that I would like to distribute now. It is an .app bundle with several folders that contain datasets, configuration files, etc.-> My_Application -> config_folder -> dataset_folder -> my_application.appI have code signed the bundle using my Developer ID. When testing on my development laptop, everything works fine. However, when I download it from Internet and open it (the usual way to distribute), even though the application is code signed it is still translocated to private\var\....It is a problem for me -- because of this translocation, configuration files cannot be changed in the "config_folder".Is there anything else I can do to have my application downloaded and opened without translocation (without changing the security settings on a computer)?Thanks a lot!
Posted
by igorland.
Last updated
.
Post not yet marked as solved
3 Replies
632 Views
Something crazy started happening in xCode 9. I use the following code to scroll the view when a keyboard is shown: func registerForKeyboardNotifications() { let notificationCenter = NotificationCenter.default notificationCenter.addObserver( self, selector: #selector(IGAFlightplanVC.keyboardWasShown(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil ) notificationCenter.addObserver( self, selector: #selector(IGAFlightplanVC.keyboardWillBeHidden(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil) } func unregisterForKeyboardNotifications() { let notificationCenter = NotificationCenter.default notificationCenter.removeObserver( self, name: NSNotification.Name.UIKeyboardWillShow, object: nil) notificationCenter.removeObserver( self, name: NSNotification.Name.UIKeyboardWillHide, object: nil) } func keyboardWasShown(_ aNotification : NSNotification) { self.info = aNotification.userInfo! as NSDictionary! let value: NSValue = info.value(forKey: UIKeyboardFrameBeginUserInfoKey) as! NSValue let keyboardSize: CGSize = value.cgRectValue.size let contentInsets: UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize.height, 0.0) if self.scrollView != nil { self.scrollView.contentInset = contentInsets self.scrollView.scrollIndicatorInsets = contentInsets var aRect: CGRect = self.view.frame aRect.size.height -= keyboardSize.height if let field = self.activeField { let activeFieldRect: CGRect = field.frame let activeFieldOrigin: CGPoint = activeFieldRect.origin if !aRect.contains(activeFieldOrigin) { self.scrollView.scrollRectToVisible(activeFieldRect, animated:true) } } else { print("Textfield is nil") } } } func keyboardWillBeHidden(_ aNotification : NSNotification) { if self.scrollView != nil {self.scrollView.setContentOffset(CGPoint.zero, animated: true)} } func textFieldDidBeginEditing(_ theTextField : UITextField) { self.activeField = theTextField theTextField.text = "" let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapDetected(_:))) if self.scrollView != nil {self.scrollView.addGestureRecognizer(tapRecognizer)} } func textFieldDidEndEditing(_ theTextField : UITextField) { self.activeField = nil; } func tapDetected(_ tapRecognizer: UITapGestureRecognizer) { self.activeField?.resignFirstResponder() if self.scrollView != nil {self.scrollView.removeGestureRecognizer(tapRecognizer)} }The scrollview moves up when I tap on the textfield and down when I tap on the view, BUT only twice or sometimes three times. After that, it stops moving the view. I have to reload the application to have it work, and it works again twice or thrice only and then stops moving the view. Never had the problem in xCode 8 before!Help would be much appreciated!EDIT: It appears to be a problem with iOS 11. It works fine on another iPad which I was smart enough not to update. Anyone has been in a similar situation?
Posted
by igorland.
Last updated
.
Post not yet marked as solved
0 Replies
347 Views
Hi. In my project, I have a UIView added to the center of Navigation Item, and then I have a UISwitch, an image and an activity indicator added to that view. So, starting from xCode 9, this configuration stopped working: the switch is no longer selectable (cannot select on or off) on devices (although can be selectable in Simulator). Can someone confirm it please? Is this a bug to be reported?Thank you!
Posted
by igorland.
Last updated
.
Post marked as solved
1 Replies
1.7k Views
Can someone please explain to me the proper way to remove all localizations from my project in xCode 9?First, I moved the files from the Base.lproj folder to the main project folder. Then, I tried to set the full path to a new file, but xCode still does not see it saying that Main.storyboard does not exist.I also tried to uncheck Base from Localization section of the right pane. It suggests that I move the localization of the Main.storyboard to English. Well, not exactly what I want. If I still do it, it tells me that it could not find the file for the Base localization on disk (well, since I moved it to the main project folder).How exactly should I proceed to remove all locations (just to have a Localize... button instead of Base or anything else)?Thanks a lot!
Posted
by igorland.
Last updated
.
Post not yet marked as solved
1 Replies
381 Views
Hello. Ever since I switched to xCode 9, using a UITextView stopped working:@IBOutlet weak var txtPirepText: UITextView! override func viewDidLoad() { if UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad { self.txtPirepText = UITextView(frame: CGRect(x: 60, y: 380, width: 900, height: 280)) print("IS THIS VALUE NIL? ",self.txtPirepText) self.txtPirepText.font = UIFont(name: "Arial-BoldMT", size: 17) self.txtPirepText.textColor = UIColor.black } }The print shows that the value is nil and the application crashes on trying to set a text. It worked just fine in the previous versions of iOS.Does such initialization not work any more? Thank you!
Posted
by igorland.
Last updated
.