I am new to programming and new to this forum.. I have a problem with stack views. Once I had implemented stack views: https://i.stack.imgur.com/7Lgf0.png my code to dismiss keyboard stopped working. When I hit the text box the keyboard appears and I can enter values. When clicking outside the text box the keyboard remains. Without Stack views all is well.. Here is the code for dismiss keyboard:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
// Hide the keyboard.
textField.resignFirstResponder()
return true
}
func textFieldDidEndEditing(_ textField: UITextField) {
}
// dismiss keyboard on touch outside textfield
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for txt in self.view.subviews {
if txt.isKind(of: UITextField.self) && txt.isFirstResponder {
txt.resignFirstResponder()
}
}
}
What am I doing wrong?? how do I get the keyboard dismiss function to work again while keeping stack views?
Try to remove everything in the touchesBegan function and just add self.view.endEditing(true) in it. I tried this with my textfield in UIStackView and this line does it all.
Swift 4.1:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
Related
I created a custom keyboard screen on tvOS.
If possible, tap on UITextField as it is, I want to transition to the custom keyboard view.
But tapping the UITextField always displays the system keyboard.
What should I do now?
1) Make the view controller implement this delegate: UITextFieldDelegate
class YourViewController: UIViewController, UITextFieldDelegate {
// ...
yourTextField.delegate = self
// ...
}
2) Return false in textFieldShouldBeginEditing, so the text field doesn't respond and the keyboard doesn't open. Instead, open yours or do whatever you want.
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
// HERE, open your keyboard or do whatever you want
return false
}
textField.inputView = UIView()
class YourViewController: UIViewController,UITextFieldDelegate { }
First set your delegate for textfieldtextField.delegate = self, Then
func textFieldDidBeginEditing(_ textField: UITextField) {
textField.addTarget(self, action: #selector(gettextFieldFunction), for: UIControlEvents.touchDown)
}
I am having trouble getting custom SKSpriteNode buttons to work with the xCode level editor on devices with 3d Touch.
I have a button subclass which is mostly based on the DemoBots sample from apple.
The basic code would be this
enum ButtonIdentifier: String {
case playButton
case pauseButton
}
/// Button responder delegate
protocol ButtonDelegate: class {
func pressed(button button: ButtonNode)
}
class ButtonNode: SKSpriteNode {
public weak var delegate: ButtonDelegate? {
return scene as? ButtonDelegate
}
var isHighlighted = false {
didSet {
// running skactions to colorise buttons and animate
}
}
var identifier: ButtonIdentifier!
/// Code init (when button is created in code)
/// e.g let playButton = ButtonNode(imageNamed: "ButtonImage", identifier: playButton)
init(imageNamed: String, identifier: ButtonIdentifier) {
self.identifier = identifier
let texture = SKTexture(imageNamed: imageNamed)
super.init(texture: texture, color: SKColor.clearColor(), size: texture.size())
name = identifier.rawValue
setup()
}
/// Level editor init (when button is created in level editor)
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// Ensure that the node has a supported button identifier as its name.
guard let nodeName = name, identifier = ButtonIdentifier(rawValue: nodeName) else {
fatalError("Unsupported button name found.")
}
self.identifier = identifier
setup()
}
private func setup() {
// zPosition
zPosition = 200
// Enable user interaction on the button node to detect tap and click events.
userInteractionEnabled = true
}
#if os(iOS)
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesBegan(touches, withEvent: event)
isHighlighted = true
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesEnded(touches, withEvent: event)
guard let scene = scene else { return }
for touch in touches {
let location = touch.locationInNode(scene)
let node = scene.nodeAtPoint(location)
if node === self || node.inParentHierarchy(self) {
runPressedAction()
} else {
isHighlighted = false
}
}
}
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
super.touchesCancelled(touches, withEvent: event)
isHighlighted = false
}
#endif
// MARK: - Pressed Action
private func runPressedAction() {
// SKAction that runs a press animation
delegate?.pressed(button: self)
}
}
If i create the button via the xCode level editor everything is working fine in the simulator or on my iPhone 6, however when using test flight my friend with a 6s Plus gets no touch input on the buttons, he cannot press them.
If I create the button all in code everything works, even on 3d touch devices.
Why is it not working with buttons from the level editor on 3d touch devices? I have been trying to look at apples demo bots sample to see if I missed some setting or something, but I cannot figure it out. (Demo bots buttons do work on my friends iPhone 6s plus)
I know that on 3d touch devices touchesMoved method gets called even though there are no changes in the x/y coordinates. However I don't think this causes my issues because when creating buttons in code everything is working as expected.
Is there some setting in the Xcode level editor I am missing to allow touches on 3d touch devices?
After days of frustration it turned out it was a iOS 9 bug. My friend was on iOS 9.2.x and after he updated to the latest iOS 9.3.x version everything is working, no code changes where required at all.
How would I go about moving an object to follow touch in the newest version of swift. So if you touch the object it will follow your finger around until you remove your finger.
You should use the touchesBegan and touchesMoved methods.
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
thing.center = (touch.locationInView(self.view))
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
thing.center = touch.locationInView(self.view)
}
}
For more info, watch this video. Hope this helps.
I want to show/hide a window in swift by clicking a button from main window. Beginsheet is showing the window, but endsheet is not closing the window. My appdelegate code is given:
import Cocoa
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
#IBOutlet weak var window: NSWindow!
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
}
func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
}
var settingsController: SettingsController?
#IBAction func inSettings(sender: NSObject?)
{
settingsController = SettingsController(windowNibName: "SettingsController")
window.beginSheet(settingsController!.window!, completionHandler: nil)
}
#IBAction func outSettings(sender: NSObject?)
{
window.endSheet(settingsController!.window!)
}
}
SettingsController:
import Cocoa
class SettingsController: NSWindowController {
override func windowDidLoad() {
super.windowDidLoad()
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}
}
Swift 3 Solution:
Lets say that you have WindowA and WindowB. You want to open WindowB but first You want to hide WindowA.
Connect windows with a segue. (Select "Show" as segues "Kind" property) And you need a static class to keep hidden window. in WindowA override shouldPerformSegue and keep WindowA as a static NSWindow object.
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
YourStaticClass.WindowA = self.view.window
self.view.window?.orderOut(self)
return true
}
orderOut(self) hides the window. Then WindowB will be opened.
In WindowB's view controller use a function to close windowB and show hidden WindowA:
#IBAction func btnBack_Click(_ sender: NSButton) {
YourStaticClass.WindowA?.makeKeyAndOrderFront(YourStaticClass.WindowA)
self.view.window?.close()
}
Use endSheet to end a document-modal sheet session. Like this:
#IBAction func outSettings(sender: NSObject?)
{
settingsController!.window!.endSheet(settingsController!.window!)
}
EDIT: You need to actually close the window in your completion handler you call orderOut, like this:
#IBAction func inSettings(sender: NSObject?)
{
settingsController = SettingsController(windowNibName: "SettingsController")
window.beginSheet(settingsController!.window!) {
settingsController!.window!.orderOut(nil)
}
}
How do I dismiss the keyboard by pressing the return key on device? I know how to dismiss keyboard, but not when using the UITextView:
resignFirstResponder
I have tried this, but it does not work:
self.messageTextView.delegate = self
And with this function:
func messageTextViewShouldReturn(textView: UITextView) -> Bool
{
self.messageTextView.resignFirstResponder()
return true
}
Remember to add the UITextDelegate into ViewDidLoad()
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
if text == "\n"
{
textView.resignFirstResponder()
return false
}
return true
}
Swift 5
unlike a textField where IBActions are available, there are no actions available for text views.
create your textViewOutlet
If you are using a tableview:
identify where your textView row is located:
let textViewIndex = IndexPath(row: 0, section: 1)
then in (_:didSelectRowAt:) dismiss the keyboard if any row other than your textView
if indexPath != textViewIndex {
textViewOutlet.resignFirstResponder()
}
if you are not using a tableview: In your SB viewcontroller, drag a UITapGestureRecognizer to your view. Then create an IBAction from that Tap Gesture Recognizer by control dragging it to your view. In the action dismiss your keyboard from your textViewOutlet:
#IBAction func tapGestureRecognizer(_ sender: Any) {
notesField.resignFirstResponder()
}