NSTableView -
taulukkonäkymä
SISÄLLYSLUETTELO
1. NSTableView ja NSArrayController
2. NSTableView ilman NSArrayControlleria
3. Taulukon riville haluttu taustarivi
Tässä käsitellään suositeltavinta TableView:tä (View Based
TableView) ja alkuosassa siten, että tietosisältö on
NSArrayControllerissa. Tästä tulee eräitä rajoituksia. Katso aivan
lopussa miten toimitaan ilman NSArrayControlleria. Otsakekuva on
joulukuinen tulvajärvi Saukkolassa.
1. Konffaus käyttöliittymäeditorissa
NSTableView itse:
- Interface Builderissa raahaa ikkunaan TableView
- Avaa Assistant editor ja ctrl-raahaa sinne
nimenomaan NSTableView (ei scrollView eikä muukaan View), anna nimi
ja tee outlet
- Attributes Inspector:
- Content Mode: View Based
- Columns: sarakkeiden
lukumäärä (mukaanlukien mahdolliset piilotettavat)
- Column sizing: None
- Alternating Rows: taulukon
ulkonäköön vaikuttava asia
- Selection: jätä kaikki
tyhjiksi (ellet halua kokeilla Type Select)
- Size Inspector: pienennä arvoja Row Height ja Cell
Spacing, jos haluat tiiviimmän näkymän
Sarakkeet (NSTableColumn):
- Identity Inspector / Identifier: jokaiselle
sarakkeelle tunniste
- Attribute Inspector
- Title: sarakkeen otsake
- State.Editable: off (vaikka
netistä löytyy muutakin ohjetta)
- Alignment: sarakkeen otsake
oikeaan reunaan jne.
- NSTableColumn -> ... ->
Table View Cell (alin taso) -> Alignment: sarakkeen tietosisällön
sijainti
- Sort Key: sama kuin edellä
Identifier
- Selector:
localizedCaseInsensitiveCompare: (ääkköset hoituu) tai
Compare: luvuille
- Size Inspector: sarakkeen leveydet
- tarvittaessa numerosaraketta varten raahaa sinne
Number Formatter, jossa voi lukuarvon määritellä haluttuun muotoon.
Ilman sitä oletuksena luvut tulee esim. "12 345" eikä 12345, joten:

Array Controller käsittelee tietosisällön. Raahaa sellainen
työkalupakista xib-näkymän vasempaan laitaan, ja konffaa se:
- Avaa Assistant editor ja ctrl-raahaa siihen
viiva Array Controller -kuvasta, tee outlet
- Identity Inspector:
- Label eli anna sille jokin
kutsumanimi (esim. arrayPaikat), ei tarvitse olla sama kuin
ArrayControllerin nimi
- Jätä tyhjäksi User Define
Runtime Attributes
- Attributes Inspector / Keys:
- Poista ruksi kohdasta 'Avoid
Empty Selection'
- Lisää avaimet vastaten TableView:n
sarakkeiden Identifierejä
Sarakkeiden (NSTableColumn) konffausta jatka, sarake kerrallaan:
- Bindings inspector / Value:
- Bind To: oma taulukkosi eli
kuvakkeen kutsumanimi IB-näytöllä
- Controller Key: =
"arrangedObjects"
- Model Key Path: oman
taulukkosi sarakkeen Identifier (siihen jää harmaa huutomerkki)
- sarakkeen oheiselle
alaosiolle Binding Inspector:

Jatka NSTableView:n konffausta
- Binding Inspector / Table Content / Content:
- Bind To: oma taulukkosi eli kuvakkeen
kutsumanimi IB-näytöllä
- Controller Key = arrangedObjects
- Binding Inspector / Table Content / Selection
indexes:
- Bind To: oma taulukkosi eli kuvakkeen
kutsumanimi IB-näytöllä
- Controller Key = selectionIndexes
- Binding Inspector / Table Content / Sort
Descriptors (mahdollistaa lajittelun):
- Bind To: oma taulukkosi eli kuvakkeen
kutsumanimi IB-näytöllä
- Controller Key = sortDescriptors
- Connections Inspector (ei pakollinen, riippuu siitä
miten lataat sisällön):
On tehtävä linkitys dataSource ja delegate.
Ctrl-raahaa componentin renkaasta vasemmalle otsakkeseen File's
Owner. Lopputuloksen on oltava tällainen:

Kaksoisklikkaus / NSTableView:
- Tämä vain jos haluat, että taulukon rivin
kaksoisklikkauksesta tulee Action
- Bindings inspector / Double Click Argument
- Bind To: oma taulukkosi eli
kuvakkeen kutsumanimi IB-näytöllä
- Controller Key =
"selectedObjects"
- Selector Name = "riviKlik:"
(muista ":") (eli nimi ohjelmamoduulille johon koodia)
- Bindings inspector / doubleClickTarget
- Bind To: File's Owner
- Model Key Path = "self"
- Selector Name = "riviKlik:"
(eli nimi ohjelmamoduulille johon koodia)
- koodissa func riviKlik(valitut: NSArray)
kertoo mitä klikkauksessa pitäisi tehdä
Taulukon sitominen ympäristöönsä on tehtävä Bordered Scroll View:n
avulla. Kaikki 4 constraintia määriteltävä.
Koodausesimerkkejä
Taulukkoa varten tiedot kerätään seuraavasti. Tämä esimerkki käyttää
tietokantaa, mutta tiedot voi toki viedä NSArrayControlleriin
vastaavalla tavalla vakiotaulukostakin. Alla olevan funktion
kutsumisen jälkeen meillä on tiedot paikoillaan taulukossa.
Tarvitaan luokkamuuttujat:
var db: FMDatabase?
var ehtoz = "" // tänne on kerätty hakuehdoista
SQL-lauseke
@IBOutlet var arrayPaikat: NSArrayController!
Ja tässä itse funktio:
// Näyttää
hakutuloksen Paikat-taulukossa
// Tätä varten tarvitaan SQL-lause, joka on muuttujassa ehtoz
// Swift 4, FMBD versio 2.7
// Output=-1: ongelma
// muu = löytyneiden paikkojen lukumäärä
func naytaHakutulosPaikka() -> Int
{
if ehtoz.isEmpty
{
return -1
}
do
{
let rs = try
db!.executeQuery(ehtoz, values: nil)
// SELECT idPaikka, Paikkanimi, kpl,
Aluenimi FROM ....
// kahdessa kentässä Int, kahdessa String
var n = 0
while rs.next()
{
let idi =
Int(rs.int(forColumn: "idPaikka")) // jos kannassa NULL,
saadaan 0
let z =
rs.string(forColumn: "Paikkanimi")
let paikkaz = (z == nil) ?
" " : z!
let az =
rs.string(forColumn: "AlueNimi")
let aluez = (az ==
nil) ? " " : az!
let kpl =
Int(rs.int(forColumn: "kpl"))
n += 1
// viedään Int, String,
String, Int
let sisus = ["idPai":idi,
"Paikka":paikkaz, "Alue":aluez, "Kpl":kpl] as [String : Any]
arrayPaikat.addObject(sisus)
}
catch
{
print("ongelma
\(error.localizedDescription)")
return -1
}
}
return n
}
Jos on tarvetta vain päivittää taulukossa yksittäinen rivi, niin
muokkaa kysely siten että tuloksena vain yksi rivi, ja tietojen haun
jälkeen:
arrayPaikat.remove(atArrangedObjectIndex:
irivi)
let sisus = ["idPai":idi, "Paikka":paikkaz, "Alue":aluez,
"Kpl":kpl]
arrayPaikat.insert(sisus, atArrangedObjectIndex: irivi)
Näytölle voidaan päivittää yhtä riviä niin että valinta säilyyy ja
rivi pysyy paikoillaan:
// Ensin ota talteen
valitun rivin indeksi:
let valittu = arrayPaikat.selectionIndex
// oltava valittu != Foundation.NSNotFound
// nyt hae korjattu data taulukkoon arrayPaikat, ks edellä
// korjatun tiedon näyttäminen:
tableviewPaikat.setNeedsDisplay(tableviewPaikat.rect(ofRow:
valittu))
Tyhjennetään näytöltä vanhat hakutulokset
arrayTau.content = nil
Rivin valinta ohjelmallisesti (jälkimmäinen tekee taulukon valituksi
ja rivin siniseksi):
arrayPaikat.setSelectionIndex(ii)
// ennen ylläolevaa tee tarkistus ii <
tableviewPaikat.numberOfRows
// jos ii on liian suuri, kaikki valinnat poistuvat
tableviewPaikat.window!.makeFirstResponder(tableviewPaikat)
Näytön skrollaus niin, että valittu saadaan keskelle. Tässä näytöllä
kerrallaan 10 riviä:
let riveja =
tableviewTiedot.numberOfRows
let iri = (valittu + 6 > riveja) ? riveja - 1 : valittu + 5
tableviewTiedot.scrollRowToVisible(iri)
Taulukon rivien lukumäärä (tuloksena Int), vaihtoehdot:
let kpl =
(arrayTiedot.arrangedObjects as AnyObject).count!
let kpl2 = (arrayTiedot.arrangedObjects as! [Any]).count
let kpl3 = tableviewTiedot.numberOfRows
Tarkistetaan onko jotain ylipäätään valittuna ja sitten käsitellään
tietoja
let indi =
arrayTiedot.selectionIndex
if indi==Foundation.NSNotFound
{
print("Ohjelmointivirhe tai rivi valitsematta")
return false
}
let kk = arrayTiedot.selectedObjects[0] as! NSDictionary
let zz = kk.value(forKey: "aluenimi") as! String
// jne.
Kerätään sarakkeen "idPaikka" tiedot talteen:
let tempx: NSArray =
arrayPaikat.arrangedObjects as! NSArray
if tempx.count == 0
{
// ei tuloksia
}
let keyz: AnyObject = "idPaikka" as AnyObject
for i in 0..<tempx.count
{
let xxx = tempx.object(at: i) as! NSDictionary
let z: String = xxx.object(forKey: keyz) as! String
// tee z:llä jotain
}
Taulukon otsakkeen vaihtaminen:
let sara =
tableTaulu.tableColumn(withIdentifier:
NSUserInterfaceItemIdentifier(rawValue: "idi"))
sara?.headerCell.attributedStringValue =
NSAttributedString(string: "idLaatu", attributes: nil)
edelläoleva sijoittaa otsikon vasempaan reunaan, laitetaan keskelle:
let paragraph
= NSMutableParagraphStyle()
paragraph.alignment = .center
sara?.headerCell.attributedStringValue =
NSAttributedString(string: "idLaatu", attributes:
[.paragraphStyle: paragraph])
Taulukon sarakkeen piiloittaminen ohjelmallisesti:
sara?.isHidden =
true //ks sara edeltä
Taulukon sarakkeelle saa määriteltyä haluamansa fontin. Tämä
vaikuttaa taulukon sisältöön, ei otsakkeisiin:
let sara =
tableviewHakutulos.tableColumn(withIdentifier:
NSUserInterfaceItemIdentifier(rawValue: "Paikka"))
let cc: NSCell = sara!.dataCell as! NSCell
cc.font = NSFont(name: "Arial", size: 11.0)
Rivin kaksoisklikkauksen pyydystys:
Laita windowDidLoad()-funktioon:
// taulukon
rivin doubleclick
tableviewTulos.target = self
tableviewTulos.doubleAction = #selector(havaDoubleklik)
Ja sitten funktioksi muiden joukkoon:
@objc func
havaDoubleklik(_ sender:AnyObject)
{
// tänne mitä pitää tapahtua valitun rivin
tiedoilla
}
Taulukon rivin valitsemalla halutaan tapahtuvan jotain (kolme
vaihtoehtoa):
Vaihtoehto 1 (#selector), jos rivin valinta tapahtuu hiirellä
klikkaamalla.
Laita windowDidLoad() -funktioon seuraava rivi:
tableviewTulos.action =
#selector(onTTItemClicked)
ja vastaava action-funktio luokan muiden funktioiden joukkoon:
@objc private
func onTTItemClicked()
{
let tt = tableviewTulos!
let iri = tt.clickedRow
let ito = tt.clickedColumn
if iri >= 0 // iri = -1,
jos klikattiin otsaketta
{
// iri, ito: tee näiden
perusteella jotain
}
}
Vaihtoehto 2 (muuttujan tarkkailija), jos rivin valinta tapahtuu
hiirellä klikkaamalla tai siirtymällä nuolinäppäimillä riviltä
toiselle. Laita windowDidLoad() -funktioon allaoleva rivi:
arrayTulos.addObserver(self,
forKeyPath: "selectionIndexes",
options:NSKeyValueObservingOptions.new, context:nil)
Tarkkailun tulos hyödynnetään korvaamalla (override) tarkkailijan
action omalla:
override func
observeValue(forKeyPath keyPath: String?, of object: Any?, change:
[NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)
{
if keyPath == "selectionIndexes"
{
let rivi =
tableviewTulos.selectedRow
if rivi == -1 //
tilanne kun taulukko tyhjennetty
{
print("TYHJÄ
rivi")
return
}
let kk =
arrayTulos.selectedObjects[0] as! NSDictionary
let failiz = kk.value(forKey:
"Pvm") as! String
// tee tuloksella jotain
}
}
Jos luokassa tarkkaillaan useaa muuttujaa, tulee vain yksi ylläoleva
funktio. Input keyPath sisältää muuttujan nimen, edellä
"selectionIndexes". Edellä olevaa funktiota tulee kutsuttua usein,
esimerkiksi kun taulukkoon arrayPaikat lisätään uusi rivi (se tulee
automaattisesti valituksi) tai kun taulukko tyhjennetään. Jos haluat
välttää ettei rivin lisäämisestä aiheudu määrittelemiäsi
toimenpiteita, käytä apumuuttujaa (esim. var ohita = true) oikeissa
paikoissa.
Tarkkailija pitää poistaa sitten, kun sitä ei enää tarvita, esim
luokan deinitiliaisoinnin yhteydessä:
deinit
{
arrayTulos.removeObserver(self, forKeyPath:
"selectionIndexes", context: nil)
}
Vaihtoehto 3 (delegaattifunktio), jos rivin valinta tapahtuu
hiirellä klikkaamalla tai siirtymällä nuolinäppäimillä riviltä
toiselle. Lisää luokan määrittelyyn delegaatti:
class
Vak_henk: NSWindowController, NSTableViewDelegate
Laita windowDidLoad()
-funktioon allaoleva rivi:
tableviewTiedot.delegate
= self
Lisää delegaattifunktio luokan muiden funktioiden joukkoon:
func
tableViewSelectionDidChange(_ notification: Notification)
{
// Nouki valittu rivi kuten edellä on kuvattu
// Tee homma mitä valinnan yhteydessä tapahtuu
}
*****************************************************************************************
2. NSTableView ilman NSArrayControlleria
Alla oleva menettely ei sovellu suoraan silloin, jos ikkunassa on
useita taulukoita. Ilman NSArrayControlleria pitäisi jokainen
taulukko sijoittaa omaan NSViewController -luokkaansa. Sitä ei ole
seuraavassa esitelty.
NSArrayController mutkistaa ohjelmointia, jos on tarvetta
esimerkiksi seuraavaan:
- halutaan lajitella rivit kahden tai useamman
sarakkeen tietojen perusteella
- halutaan käyttää samaa tietolähdettä useaan eri
taulukkoon, tai esimerkiksi NSTableView:hen ja NSCollectionView:hen
- halutaan pitää sama rivi valittuna tietojen
muokkausten jälkeen
Lisäksi taulukot tuntuvat toimivan luikkaammin ilman
NSArrayControlleria.
Interface Builderissa rakenna taulukko ja sarakkeet:
NSTableView itse:
- Interface Builderissa raahaa ikkunaan TableView
- Avaa Assistant editor ja ctrl-raahaa sinne
nimenomaan NSTableView (ei scrollView eikä muukaan View), anna nimi
(esim. tableviewTulos) ja tee outlet
- Attributes Inspector:
- Content Mode: View Based
- Columns: sarakkeiden
lukumäärä (mukaanlukien mahdolliset invisible)
- Column sizing: None
- Alternating Rows: taulukon
ulkonäköön vaikuttava asia
- Selection: jätä kaikki
tyhjäksi
- Size Inspector: pienennä arvoja Row
Height ja Cell Spacing, jos haluat tiivimpmän näkymän
Sarakkeet (NSTableColumn):
- Identity Inspector / Identifier: jokaiselle
sarakkeelle tunniste
- Attribute Inspector
- Title: sarakkeen otsake
- State.Editable: off (vaikka
netistä löytyy muutakin ohjetta)
- Alignment: sarakkeen otsake
oikeaan reunaan jne.
- NSTableColumn -> ... ->
Table View Cell (alin taso) -> Alignment: sarakkeen tietosisällön
sijainti
- Sort Key ja Selector: ei
mitään, koodaat itse, ks. alempana
- Size Inspector: sarakkeen leveydet
- tarvittaessa numerosaraketta varten raahaa sinne
Number Formatter, jossa voi lukuarvon määritellä haluttuun muotoon.
Ilman sitä oletuksena luvut tulee esim. "12 345" eikä 12345:

Koodaus:
Luokan nimessä määrittele TableView:tä varten tieto, että
taulukkonäkymän ja tietolähteen tuki löytyvät samasta luokasta:
class Tabikku:
NSWindowController, NSTableViewDelegate, NSTableViewDataSource
Luokkamuuttujiksi myös sarakkeiden tämän hetken lajittelujärjestys
ja taulukko, josta data otetaan (luokkien taulukko):
var sortnimiAscending =
true
var sortpvmAscending = true
var kuvat = [Kuvainfo]()
@IBOutlet weak var tableviewTulos: NSTableView!
Tässä Kuvainfo on luokka, joka pitää erikseen määritellä, esimerkki
alla. Luokan muuttujista ei tarvitse kaikkia käyttää
taulukkonäkymässä, käytettävät kerrotaan koodissa:
class Kuvainfo:
NSObject
{
@objc var idKuva: Int = -1
@objc var Pvm: String = ""
@objc var Nimi: String = ""
@objc var kuva: NSImage? = nil
@objc var polkuz: String = ""
@objc init(idKuva: Int, .....)
{
....
}
}
Luokan muodostajaan windowDidLoad() lisää rivit:
tableviewTulos.delegate
= self // tämäkin on tarpeen!
tableviewTulos.dataSource = self
Seuraavat taulukkonäkymän tukifunktiot tarvitaan (eka ja kolmas ovat
pakollisia):
func
tableView(_ tableView: NSTableView, objectValueFor tableColumn:
NSTableColumn?, row: Int) -> Any? { }
func tableView(_ tableView: NSTableView, mouseDownInHeaderOf
tableColumn: NSTableColumn) { }
func numberOfRows(in tableView: NSTableView) -> Int
{
return kuvat.count
}
Ensimmäinen vie sisällön taulukosta kuvat taulukkonäkymään.
Toinen lajittelee taulukon sen sarakkeen mukaan, jonka otsaketta
käyttäjä klikkaa.
Kolmas kertoo taulukon koon.
Näillä funktioilla taustajärjestelmät hoitavat taulukkonäkymää ja
käyttäjän toimenpiteitä.
Funktioiden sisällä on minun omia muuttujiani ja vakioitani
seuraavasti:
func
tableView(_ tableView: NSTableView, objectValueFor tableColumn:
NSTableColumn?, row: Int) -> Any?
{
var result: Any? = nil
let saraid = tableColumn!.identifier
if saraid.rawValue == "idKuva"
{
result = kuvat[row].idKuva
}
// ... jne.
return result
}
func tableView(_ tableView: NSTableView, mouseDownInHeaderOf
tableColumn: NSTableColumn)
{
let saraid = tableColumn.identifier
if saraid.rawValue == "Nimi"
{
if sortnimiAscending
{
//kuvat.sort(by: {$0.Nimi < $1.Nimi})
kuvat.sort(by: {$0.Nimi.localizedCaseInsensitiveCompare($1.Nimi)
== ComparisonResult.orderedAscending})
}
else
{
//kuvat.sort(by: {$0.Nimi > $1.Nimi})
kuvat.sort(by: {$0.Nimi.localizedCaseInsensitiveCompare($1.Nimi)
== ComparisonResult.orderedDescending})
}
sortnimiAscending =
!sortnimiAscending
tableviewTulos.reloadData() // muutokset näkyviin
}
// ... jne. muut sarakkeet
}
Sovelluksen alussa viedään taulukkoon kuvat sisältö, ja kun
aloitusfunktiot on suoritettu, myös taulukkonäkymässä ovat tiedot
paikoillaan. Taulukon kuvat
tietoja voi myöhemmin muuttaa vaikkapa vain yhden tiedon osalta
(esimerkiksi päivämäärää), minkä jälkeen seuraavalla
komennolla taulukkonäkymä päivittyy ja säilyy samalla kohdalla:
tableviewTulos.reloadData()
Taulukot tyhjennetään kokonaan näin:
kuvat.removeAll()
tableviewTulos.reloadData()
Mikä rivi on taulukossa valittuna:
let kk =
tableviewTulos.selectedRow
let irivi = (kk == -1) ? -1 : kuvat[kk].idKuva
// jos tarkoitus oli että aina on joku valittuna, niin saat
kk-arvosta tehtyä virheilmoituksen
Tehdään valituksi rivi kuvat[iri]:
tableviewTulos.selectRowIndexes(NSIndexSet(index:
i) as IndexSet, byExtendingSelection: false)
// tehdään taulukko valituksi jolloin valitusta rivistä sininen:
tableviewTulos.window!.makeFirstResponder(tableviewTulos)
Näytön skrollaus niin, että valittu saadaan keskelle. Tässä näytöllä
kerrallaan 10 riviä:
let riveja =
tableviewTulos.numberOfRows
let iri = (valittu + 6 > riveja) ? riveja - 1 : valittu + 5
tableviewTulos.scrollRowToVisible(iri)
Taulukon rivien lukumäärä (tuloksena Int), vaihtoehdot:
let kpl =
tableviewTulos.numberOfRows
Taulukon sarakkeelle saa määriteltyä haluamansa fontin. Tämä
vaikuttaa taulukon sisältöön, ei otsakkeisiin:
let sara =
tableviewHakutulos.tableColumn(withIdentifier:
NSUserInterfaceItemIdentifier(rawValue: "Paikka"))
let cc: NSCell = sara!.dataCell as! NSCell
cc.font = NSFont(name: "Arial", size: 11.0)
Rivin kaksoisklikkauksen pyydystys:
Laita windowDidLoad()-funktioon:
// taulukon
rivin doubleclick
tableviewTulos.target = self
tableviewTulos.doubleAction = #selector(havaDoubleklik)
Ja sitten funktioksi muiden joukkoon:
@objc func
havaDoubleklik(_ sender:AnyObject)
{
// tänne mitä pitää tapahtua valitun rivin
tiedoilla
}
Taulukon rivin valitsemalla halutaan tapahtuvan jotain (kaksi
vaihtoehtoa):
Vaihtoehto 1 (delegaattifunktio), jos rivin valinta tapahtuu
hiirellä klikkaamalla tai siirtymällä nuolinäppäimillä riviltä
toiselle. Lisää luokan määrittelyyn delegaatti:
class
Vak_henk: NSWindowController, NSTableViewDelegate
Laita windowDidLoad()
-funktioon allaoleva rivi:
tableviewTiedot.delegate
= self
Lisää delegaattifunktio luokan muiden funktioiden joukkoon:
func
tableViewSelectionDidChange(_ notification: Notification)
{
// Nouki valittu rivi kuten edellä on kuvattu
// Tee homma mitä valinnan yhteydessä tapahtuu
}
Vaihtoehto 2 (#selector), jos rivin valinta tapahtuu hiirellä
klikkaamalla.
Laita windowDidLoad() -funktioon seuraava rivi:
tableviewTulos.action =
#selector(onTTItemClicked)
ja vastaava action-funktio luokan muiden funktioiden joukkoon:
@objc private
func onTTItemClicked()
{
let tt = tableviewTulos!
let iri = tt.clickedRow
let ito = tt.clickedColumn
if iri >= 0 // iri = -1,
jos klikattiin otsaketta
{
// iri, ito: tee näiden
perusteella jotain
}
}
********************************************************************************
3. Taulukon riville haluttu taustaväri
Tarvitaan delegaatti NSTableViewDelegate ja sille funktio
func
tableView(_ tableView: NSTableView, rowViewForRow row: Int) ->
NSTableRowView?
{
return OmaRowView()
}
Taustaväri järjestetään toimenpiteellä "Subclassing of
NSTableRowView":
class
OmaRowView: NSTableRowView
{
//-------------------------------------------
// 18.12.2021 R12
// Riville haluttu taustaväri
override func drawSelection(in dirtyRect:
NSRect)
{
if
self.selectionHighlightStyle != .none
{
let
selectionRect = NSInsetRect(self.bounds, 1.0, 1.0) //, 2.5, 2.5)
let
valittu = NSColor(red: 240/255, green: 230/255, blue: 140/255,
alpha: 1.0)
valittu.setFill()
let
selectionPath = NSBezierPath.init(roundedRect: selectionRect,
xRadius: 0, yRadius: 0)
selectionPath.fill()
}
}
}
Jos lisäksi halutaan, että teksti ei ole valinnassa inverted
(valkoinen), niin edellä olevaan luokkaan lisätään funktiot:
override var
isEmphasized: Bool
{
set {}
get { return false }
}
override var selectionHighlightStyle:
NSTableView.SelectionHighlightStyle
{
set {}
get { return .regular }
}
--------------------------------
(sivua muokattu 8.1.2021)