UISegmentedControl selected Segment always -1 - xcode

I subclassed UISegmentedControl in order to trigger the valueChanged method which works fine. Now when I select a segment the index is always -1.
I am on Xcode 6 beta 4, I can't find what I am doing wrong.
The subclass:
import UIKit
class MySegCotrl: UISegmentedControl {
init(coder aDecoder: NSCoder!) {
super.init(coder: aDecoder)
}
override func touchesEnded(touches: NSSet!, withEvent event: UIEvent!) {
let current = self.selectedSegmentIndex
super.touchesBegan(touches, withEvent: event)
println("Current:\(current)")
println("Self.selectedSegmentIndex:\(self.selectedSegmentIndex)")
if current == self.selectedSegmentIndex {
self.sendActionsForControlEvents(UIControlEvents.ValueChanged)
}
}
}
The valueChanged method in my UIViewController class
#IBOutlet var segCotrRelevanz: MySegCotrl!
#IBAction func relevanChanged(sender: AnyObject) {
println("sender.selectedSegmentIndex:\(sender.selectedSegmentIndex)")
println("segCotrRelevanz.selectedSegmentIndex:\(segCotrRelevanz.selectedSegmentIndex)")
if sender.selectedSegmentIndex == segCotrRelevanz.selectedSegmentIndex {
println("Same")
}
}
The output:
Current:-1
Self.selectedSegmentIndex:-1
sender.selectedSegmentIndex:-1
segCotrRelevanz.selectedSegmentIndex:-1
Same

Try change method to touchesBegan not touchesEnded, left all as it should be:
override func touchesBegan(touches: NSSet!, withEvent event: UIEvent!) {
let current = self.selectedSegmentIndex
super.touchesBegan(touches, withEvent: event)
println("Current:\(current)")
println("Self.selectedSegmentIndex:\(self.selectedSegmentIndex)")
if current == self.selectedSegmentIndex {
self.sendActionsForControlEvents(UIControlEvents.ValueChanged)
}
}

Related

Reload tableView with delegation

I'm trying to avoid the use of notifications with delegation. I need to reload a tableView selecting a row on another tableView, but reloadData() is not working.
protocol GroupDelegate {
func groupDidSelectRow(selectedRow: Int)
}
class GroupTableView: NSTableView, NSTableViewDelegate, NSTableViewDataSource, NSMenuDelegate {
var groupDelegate:GroupDelegate?
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
self.delegate = self
self.dataSource = self
self.groupDelegate = TemplateTableView()
}
func tableViewSelectionDidChange(_ notification: Notification) {
groupDelegate?.groupDidSelectRow(selectedRow: self.selectedRow)
}
}
class TemplateTableView: NSTableView, NSTableViewDelegate, NSTableViewDataSource, GroupDelegate {
var groupSelectedRow = 0
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
self.delegate = self
self.dataSource = self
}
func groupDidSelectRow(selectedRow: Int) {
groupSelectedRow = selectedRow
reloadData() // This line is not working
}
}

NSCollectionView (osx 10.11) hangs when running

I've made a subclass of NSCollectionView which conforms to NSCollectionViewDataSource, NSCollectionViewDelegate but it hangs everytime - I only get the spinning beach ball.
public class SequenceCollectionView : NSCollectionView, NSCollectionViewDataSource, NSCollectionViewDelegate {
// MARK: Inits
public required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
commonInit()
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
func commonInit() {
self.dataSource = self
self.delegate = self
}
//MARK: Datasource
public func collectionView(collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
public func collectionView(collectionView: NSCollectionView, itemForRepresentedObjectAtIndexPath indexPath: NSIndexPath) -> NSCollectionViewItem {
if indexPath.item == 0 {
let item = NSCollectionViewItem(nibName: "ItemView", bundle: nil)
}
return NSCollectionViewItem()
}
}
It's obviously in some kind of loop or retain cycle but I'm finding it hard to debug.
It transpires that the issue lies with the optional delegate call
public func collectionView(collectionView: NSCollectionView, willDisplayItem item: NSCollectionViewItem, forRepresentedObjectAtIndexPath indexPath: NSIndexPath) {
}
By adding this to the class has fixed the issue.
Adding to Chris' answer, the NSCollectionView will hang on scrolling or resizing the view unless the following optional delegate method is overriden:
- (void)collectionView:(NSCollectionView *)collectionView didEndDisplayingItem:(NSCollectionViewItem *)item forRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath {}

Why won't my Interstitial Ads work in my GameScene but work in the GameViewController in Swift?

I have these facebook interstitial ads and when I call them in my GameScene they dont show up. They work perfectly when I call them in the GameViewController but not in my GameScene. Can someone tell me what Im doing wrong with my code?
//GameViewController.swift
class GameViewController: UIViewController, FBInterstitialAdDelegate {
let interstitialFBAD: FBInterstitialAd = FBInterstitialAd(placementID: "65543456456456_454345345454534")
override func viewDidLoad() {
super.viewDidLoad()
}
//CALL THIS IN MY GAMESCENE.
func loadFBInterstitialAd() {
interstitialFBAD.delegate = self
interstitialFBAD.loadAd()
}
func interstitialAdDidLoad(interstitialAd: FBInterstitialAd!) {
interstitialFBAD.showAdFromRootViewController(self)
}
//GameScene.swift
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let location = touch.locationInNode(self)
let node = self.nodeAtPoint(location)
if node.name == "retry" {
GameViewController().loadFBInterstitialAd()
}
}
}
In viewDidLoad of GameViewController register for a notification, and later from the GameScene post a notification when you want the ad to appear.
so your viewDidLoad will have the following extra line
NSNotificationCenter.defaultCenter().addObserver(self, selector: "loadFBInterstitialAd", name: "loadAd", object: nil)
then write a method in Gamescene
func showAdNow() {
NSNotificationCenter.defaultCenter().postNotificationName("loadAd", object: nil)
}
now in Gamescene.swift replace the line
GameViewController().loadFBInterstitialAd()
with
showAdNow()
You try:
//GameViewController.swift
class GameViewController: UIViewController, FBInterstitialAdDelegate {
let interstitialFBAD: FBInterstitialAd = FBInterstitialAd(placementID: "65543456456456_454345345454534")
var scene: GameScene!
override func viewDidLoad() {
super.viewDidLoad()
let skView = view as! SKView
skView.multipleTouchEnabled = false
scene = GameScene(size: skView.bounds.size)
scene.scaleMode = .AspectFill
scene.view?.userInteractionEnabled = true
skView.presentScene(scene)
scene.gvcDelegate = self
}
//GameScene.swift
class GameScene: SKScene {
gvcDelegate: GameViewController?
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let location = touch.locationInNode(self)
let node = self.nodeAtPoint(location)
if node.name == "retry" {
gvcDelegate.loadFBInterstitialAd()
}
}
}
Goodluck!

Is it possible to make #IBDesignable override Interface Builder values?

For example, I want to subclass UIButton and set it's font to 20.0f by default. I can write something like this:
#IBDesignable
class HCButton: UIButton {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.customInit()
}
func customInit () {
titleLabel?.font = UIFont.systemFontOfSize(20)
}
}
But this does not affect preview in Interface Builder, all custom buttons appear with 15.0f font size by default. Any thoughts?
I have created new IBInspectable as testFonts :
import UIKit
#IBDesignable
class CustomButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
self.customInit()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.customInit()
}
func customInit () {
titleLabel?.font = UIFont.systemFontOfSize(20)
}
convenience init() {
self.init(frame:CGRectZero)
self.customInit()
}
override func awakeFromNib() {
super.awakeFromNib()
self.customInit()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
self.customInit()
}
}
Hope it helps you :)
This is working for me.
I think you must override the init with frame initializer as well to affect that
override init(frame: CGRect) {
super.init(frame: frame)
self.customInit()
}
EASIER: The following solution usually works or me
import UIKit
#IBDesignable
class CustomButton: UIButton {
open override func layoutSubviews() {
super.layoutSubviews()
customInit()
}
func customInit () {
titleLabel?.font = UIFont.systemFontOfSize(20)
}
}
I hope that's what you're looking for.

xcode 6 drawing line error

Hi everyone i am making a sprite-kit app in which the user must be able to draw multiple lines. To do this I made the following code.
import SpriteKit
class GameScene: SKScene {
var line = SKShapeNode()
var path = CGPathCreateMutable()
var touch: UITouch!
var location:CGPoint!
override func didMoveToView(view: SKView) {
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
/* Called when a touch begins */
touch = touches.anyObject() as UITouch!
location = touch.locationInNode(self)
drawLine()
}
override func touchesEnded(touches: NSSet!, withEvent event: UIEvent!) {
self.delete(line)
}
func drawLine() {
CGPathMoveToPoint(path, nil, location.x, location.y)
CGPathAddLineToPoint(path, nil, 500.0, 500.0)
line.path = path
line.strokeColor = UIColor.redColor()
line.lineWidth = 5.0
self.addChild(line)
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}
This works but when the users tries the draw the second line the application crashes.
Can someone explain to me why that is happening?
------Edit------
I think i need to use an array of lines so I did something like this:
var line: [[SKShapeNode]] = []
which gives me the following error:
[[SKShapeNode]] does not have a member named 'path'.
So I though I had to make the path variable an array as well but that only gave me a second error: GameScene does not have a member named 'path'. So I changed it all back but I still think I have to use an array although I can't really figure out how to make it work.
Copy and paste this..now you'll redefine your line every time
import SpriteKit
class GameScene: SKScene {
var line = SKShapeNode()
var path = CGPathCreateMutable()
var touch: UITouch!
var location:CGPoint!
override func didMoveToView(view: SKView) {
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
/* Called when a touch begins */
touch = touches.anyObject() as UITouch!
location = touch.locationInNode(self)
drawLine()
}
override func touchesEnded(touches: NSSet!, withEvent event: UIEvent!) {
self.delete(line)
}
func drawLine() {
CGPathMoveToPoint(path, nil, location.x, location.y)
CGPathAddLineToPoint(path, nil, 500.0, 500.0)
SKShapeNode *line = [SKShapeNode node]; //redfine line every time
line.path = path
line.strokeColor = UIColor.redColor()
line.lineWidth = 5.0
self.addChild(line)
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}

Resources