preferredFocusedView for tvOS - swift

I am looking at Apple documentation here and not able to implement it in my swift project. I want to set a UIButton as the first focused in View when the app starts but cant figure out how.
I am primarily looking to do something like this:
override func preferredFocusedView .... but obviously that is not it

It's a property, not a function, so you need to do this in Swift:
override weak var preferredFocusedView: UIView? {
get {
return viewYouWantToFocus
}
}

In your UIViewController override get{} for preferredFocusedView to return your UIButton. Then make sure to call setNeedsFocusUpdate(). That should do it. (You can also implement set{} so that you can easily change which object receives focus, but again, remember to call setNeedsFocusUpdate() after changing it).

Related

UITextView dataDetector is not working in tableViewCell

I have a UITextView in a TableViewCell and I wanted to enable data detection in the textView in order to show clickable links and Phone numbers.
So I did this in storyBoard
These steps didn't work so I did the same in code.
#IBOutlet weak var postDescTextView: UITextView!
override func layoutSubviews() {
super.layoutSubviews()
postDescTextView.isUserInteractionEnabled = true
postDescTextView.isSelectable = true
postDescTextView.dataDetectorTypes = .all
}
But none of the steps seems to work.
There is clearly something I'm doing wrong. I'm pretty sure the answer is a simple one. I've found some similar questions like these.
Question 1
Question2
But unlike these questions, I don't want my TextView editable nor I don't want to be able to select The TableViewCell. Just need to make the Datalink detection work in a TableViewCell.
If you're trying to make postDescTextView programmatically remove everything else and add the following.
postDescTextView.isEditable = false
postDescTextView.dataDetectorTypes = .all
Or if you have a storyboard
Note: If you're using the programmatic approach there is no need for giving it in viewDidLayout which gets called every time there's a layout change. Give it in the init method instead.

How to catching doubleClick events from NSOutlineView in ViewController?

I am trying to catch doubleClick events from my NSOutlineView to be passed to my ViewController. My idea is to catch doubleClick events and to get the selected row from my OutlineView
What I did so far was subclassing the NSOutlineView in order to overwrite mouseDown
override func mouseDown(with event: NSEvent) {
super.mouseDown(with: event)
if event.clickCount >= 2 {
...
}
}
That works well however I don't know how to pass this event to my ViewController. The ViewController is already implementing the NSOutlineViewDelegate protocol.
I guess that the solution is not far away but somehow I am stuck.
UPDATED
Although you can set up NSGestureRecognizer for single click and NSClickGestureRecognizer for double clicks in OSX, You should probably be using the doubleAction property of the NSOutlineView directly.
Here's an example of how to set it up
This comes from a another of the Wenderlich tutorials, and there is a good discussion on SO already

Shake Gesture not Working

I have a project set up using SWReveal for the slide out menu.
When I place a motion ended override function it never seems to be called even though everything else in the class loads (indicated with the 'loading'.
I have had a good play around and found that if I change the segue to the page to a 'show' segue the code functions as I would expect it to.
However when I use a custom segue with the SWReveal as the class the motion ended does not work.
I have attached a screen shot to help describe the issue.
Any help much appreciated.
You need to override canBecomeFirstResponder method.
override func canBecomeFirstResponder() -> Bool {
return true
}

pickerDidSettle() not called

In one of my Watch Extension's interface controllers I have several WKInterfacePicker elements, and I need to know when the user has selected a value. According to documentation, WKInterfaceController should be able to implement pickerDidSettle(_:) method that has the corresponding picker element as parameter. For some reason the method never gets called when I use the pickers. Here is the basic structure of my implementation:
override func pickerDidSettle(picker: WKInterfacePicker) {
// Code inside this block is not called
}
If I mark the function with an #IBAction attribute and connect them with the picker elements in interface builder, the instance method works. However, this apparently prevents me to assign picker actions that receive all the picker values through which the user is scrolling.
#IBAction
override func pickerDidSettle(picker: WKInterfacePicker) {
// This function gets called, but blocks other actions
}
My interface controller inherits from WKInterfaceController and conforms to two custom protocols. How should I implement the method?
Edit: The issue was related to a possible bug in WatchKit, where pickerDidSettle(_:) will not be called without an existing #IBAction connection to the controller. I assume it is a bug, because related instance methods pickerDidFocus(_:) and pickerDidResignFocus(_:) work independent of the connection.
Sometimes this issue occurs, when something gets 'out of sync' between Xcode and the Simulator.
Just close the Simulator and clean and rebuild your app (via 'Product/Clean Build Folder') to recreate the 'sync.

SWRevealViewController conflict with UISlider

I currently facing an issue trying to delegate SWRevealViewController panGestureRecognizer method in one of my view.
When i slide my UISlider, the panGesture interfer and open the sidemenu instead to move my slider.
i tried to delegate the panGesture and it works well, but if i quit my view and go to an other, the pangesture is not functionnal anymore, and i can't reveal my sidemenu from my second view.
My code :
class Search : UIViewController, UIGestureRecognizerDelegate{
#IBOutlet weak var sliderprice: UISlider!
override func viewDidLoad() {
super.viewDidLoad()
self.revealViewController().panGestureRecognizer().delegate = self
}
override func viewDidAppear(animated: Bool) {
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
if (touch.view == self.sliderprice){
return false
}
else{
return true
}
}
}
While this is an old question, I'll answer it anyways, maybe for someone coming from Google search it will be helpful.
After many hours of research and thinking, finally I was able to come up with multiple solutions to this problem.
The Lazy
This solution is not recommended, but working, so I decided to list it.
Before setting self as self.revealViewController().panGestureRecognizer()'s delegate, store the original self.revealViewController().panGestureRecognizer().delegate to a property, and when you leave the screen at viewWillDisappear(), set self.revealViewController().panGestureRecognizer().delegate back to the one you stored in viewDidLoad(). So in the end it gets back its original delegate. Tampering with delegates like this is never really recommended, but I said, it works.
The Nicer One
I consider this still not the best solution, but we are getting there. Find a class, a controller that you use in the whole application and gets called when you start the app. Here set the SWRevealViewController's panGestureDelegate to this class, and overwrite the gestureRecognizerShouldBeginmethod appropriately (see below).
The Best One - (in my opinion)
Now this is the best and most clear solution.
For the time being (May, 2018) the last commit to SWRevealViewController was in 2015.
Fork the original project ( https://github.com/John-Lluch/SWRevealViewController ) or simply copy the two necessary files (SWRevealViewController.m and SWRevealViewController.h) and place them into a separate folder to handle 3rd party libraries. Then you can remove SWRevealViewController from your Podfile. Don't forget to fix your imports for SWRevealViewController where you have it.
Now you are free to modify the files. What I suggest is the following.
Go to SWRevealViewController.m and implement the following method:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldReceiveTouch:(UITouch *)touch
{
return ![touch.view isKindOfClass:UISlider.class];
}
If the touched view is a UISlider (or a custom class that inherits from UISlider) the gesture won't begin, meaning the pan gesture will no longer be conflicted with the UISlider's pan gesture.
I seriously hope I could help anyone out there as this problem was a pain in my back for quite some time now.