Как я могу закруглить углы только одной стороны NSButton в Swift 4? - PullRequest
0 голосов
/ 16 марта 2019

Я новичок в Swift и Stack Overflow в целом, поэтому я надеюсь, что не буду сильно просить меня.

Я пытаюсь создать «сгруппированный» стиль кнопок, который можно найти в Finder или на панели инструментов редактора XCode, , как эти две группы кнопок . Как видно из первой группы кнопок, левая кнопка закруглена только с левой стороны, центральная кнопка вообще не закруглена, а правая кнопка округлена только с правой стороны. То же самое относится ко второй группе кнопок. Я хочу сделать что-то подобное, но я не уверен, как этого достичь.

После поиска решения в Интернете (включая учебные пособия по iOS) я попытался предоставить расширение для класса NSButton и вручную округлить два левых угла следующим образом:

// Extensions.swift

extension NSButton {
    func roundLeftCorners() {
        self.layer?.maskedCorners = [.layerMinXMinYCorner, .layerMinXMaxYCorner]
        self.layer?.cornerRadius = 20.0   // Some arbitrary number, just wanted to make the rounded corner visible
        self.layer?.masksToBounds = true
    }
}

Затем в функции viewDidLoad() контроллера моего представления я попытался вызвать этот элемент:

// MyViewController.swift

class MyViewController: NSViewController {
    @IBOutlet weak var leftButton: NSButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        leftButton.roundLeftCorners()
    }

    // ...
}

... но это не сработало для меня. Некоторая простая отладка показала, что Optional значения self.layer были nil, поэтому я не уверен, что там происходит.

Затем я попытался создать свой собственный класс и переопределить функцию draw(_ dirtyRect:) с помощью того же кода, что и выше:

// LeftButton.swift

class LeftButton: NSButton {
    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)

        self.layer?.maskedCorners = [.layerMinXMinYCorner, .layerMinXMaxYCorner]
        self.layer?.cornerRadius = 20.0
        self.layer?.masksToBounds = true
    }
}

// MyViewController.swift

class MyViewController: NSViewController {
    @IBOulet weak var leftButton: LeftButton!

    // ...
}

... но это не убрало закругленные углы на правой стороне. Как ни странно, новое значение cornerRadius очевидно только в том случае, если число составляет 50.0 или больше; чуть меньше, и левые углы выглядят точно так же, как и любые другие NSButton.

В некоторых ответах упоминается рисование точек на пути с помощью NSBezierPath, но это не дает того, чего я хочу. Я также не могу найти связанные свойства / атрибуты в редакторе раскадровки. Возможно, я слишком усложнил свой подход к этой, казалось бы, легкой проблеме, или, может быть, я не смотрю на это правильно, но я надеюсь, что кто-то может помочь мне с этим. Заранее спасибо!

1 Ответ

1 голос
/ 17 марта 2019

1) Изображения, которые вы показали, используют простой NSSegmentedControl. Ничего не нужно настраивать.

2) То, что вы пытались сделать, не сработало бы в любом случае; Если бы он мог работать механически, то в конечном итоге он просто вырезал нарисованный контент в левых углах. Он не будет волшебным образом заполнять рисунок справа и создавать соответствующие контрольные границы и т. Д.

Элементы управления AppKit - это не просто CALayers с заполненными свойствами, такими как border, background и т. Д. Они почти все полностью прорисованы с использованием Core Graphics с помощью классического метода drawRect: так или иначе. Тот факт, что у представлений есть слой, связан с поддержкой слоев. Есть очень немного вещей, которые вы можете сделать со слоем существующего элемента управления. Чтобы правильно настроить их, вы должны переопределить стандартные процедуры рисования в NSView, NSControl, NSCell и т. Д. В зависимости от ситуации.

...