cgrect swift что это

Swift: CGRect, CGSize & CGPoint

You’re (probably) doing it wrong

It’s been about a solid eight months since I first decided to jump completely into the Swift wormhole. Over those months I’ve slowly learned to stop writing Objective-C style code patterns with Swift syntax, and started to actually take advantage of the new language.

But one thing I’ve recently picked up on is that I’m still using ugly non-Swift-like syntax with all my CGGeometry structures.

C syntax. A sheep in wolf’s clothing

I have a big feeling that a lot of Swift developers are going to be guilty of this. Raise your hand if you have been using either of these in your code:

Update: As of Swift 3, these functions have been removed.

Yea, I thought so. But don’t worry, it’s nothing to be ashamed of …yet.

The thing that’s wrong with this is that it breaks Swift’s coding convention, it will still work, but it looks a lot more like something that if it belongs in Objective-C or even, dare I say it, Java. *shudders*

To a seasoned iOS or OSX developer, with a short glance they could easily tell you what that code is doing. They don’t need argument labels on CGGeometry structures because everyone knows those arguments, and their sequence off by heart. Except they don’t.

A lot of what Swift is about is being friendly to language newcomers as well as complete programming beginners. If they were to look at that code, they would have no idea what those numbers represent. So let’s all vow to be good Swift citizens and start using the Swift versions:

Update: As of Swift 3, these functions have been removed.

While we’re at it, you’re probably still using these too, amirite? lel.

We should also be updating these to use the newer, Swiftier syntax. But don’t worry, the syntax is only just an extra character longer. Can you guess what it is?

Value retrieval

Update: As of Swift 3, these functions have been removed.

If you were or still are a good Objective-C citizen, you would have used these value getters when you wanted a specific value of the rect. But wait a second, why don’t we just access the values directly?

For this reason, your applications should avoid directly reading and writing the data stored in the CGRect data structure. Instead, use the functions described here to manipulate rectangles and to retrieve their characteristics.

There’s probably still a lot of you that didn’t bother with such formalities, but that’s ok. Swift has alleviated us of such an unpretty API and instead provided simple dot notation variables.

There’s plenty more examples of these niceties available in the Swift playgrounds I’ve provided to supplement this post. The link will be at the bottom of the page.

Mutability

Not only are you able to change individual values of a view’s frame, but you’re also able to replace entire sub-structs completely. Behold:

This little feature alone is enough of a reason to stop using Objective-C. Mutability on CGRect s without having to create a new one entirely and reset the value. It was only less than two years ago that we as Objective-C developers were forced to write frame modification code like this:

I don’t know about you, but writing that really stressed me out. Creating a newFrame struct from the view ’s frame, modifying it, and then resetting the frame property on the view again. No thank you, not ever, ever again please.

Don’t forget

There are also a couple of other constructs within UIKit for which these changes are applicable to:

Sample code of this post can be found on GitHub.

Источник

Туториал по Core Graphics: градиенты и контексты

Туториал по Core Graphics: градиенты и контексты

Из этого туториала по Core Graphics вы узнаете, как разработать современное приложение для iOS с продвинутыми элементами Core Graphics, такими как градиенты и трансформации.

В этой статье мы научимся рисовать градиенты и манипулировать CGContexts с преобразованиями.

Core Graphics

Теперь вам придется покинуть уютный мир UIKit и окунуться в подземелья Core Graphics.

Это изображение от Apple концептуально описывает соответствующие фреймворки:

Фреймворк Core Graphics основан на продвинутом движке Quartz. Это обеспечивает низкоуровневый, легкий 2D рендеринг. Вы можете использовать этот фреймворк для обработки изображений на основе контуров, их преобразований, управления цветами и многого другого.

Читайте также:  что делает торгово промышленная палата

Давайте начнем

К концу данного туториала вы создадите некий график, который будет выглядеть примерно так:

Прежде выводить информацию на графике, вы настроите его в Storyboard и создадите код, который создает анимированный переход и показывает график.

Полная иерархия представлений будет выглядеть следующим образом:

Сначала загрузите материалы проекта. Когда вы откроете проект, вы заметите, что он очень похож на то, что у вас получилось после прохождения предыдущего туториала. Единственная отличие от проекта из предыдущего туториала состоит в том, что в Main.storyboard CounterView находится внутри другого представления с желтым фоном. Запустите проект, вот что вы увидите:

Создание графа

Измените константы ограничений в Size Inspector, чтобы они соответствовали константам, приведенным на изображении:

Ваш Document Outline должен выглядеть так:

Причина, по которой вам нужен Container View, заключается в том, что без него не получиться сделать анимированный переход между Counter View и Graph View.
Перейдите в раздел ViewController.swift и добавьте аутлеты свойств для Container view и Graph view.

Это создает аутлет для Container view и Graph view. Теперь подключите их к представлениям, которые вы создали в Storyboard.
Вернитесь к Main.storyboard и перетащите Container view и Graph view к соответствующим аутлетам:

Настройка анимированного перехода

Все еще находясь в разделе Main.storyboard, перетащите Tap Gesture Recognizer из Object Library в Container View в Document Outline.

Затем, перейдите в ViewController.swift и добавьте это свойство в начало класса:

Это свойство указывает, отображается ли в данный момент представление графика.

Теперь добавьте этот метод касания, чтобы сделать переход:

Если пользователь нажимает кнопку “+” во время отображения графика, дисплей поворачивается назад, чтобы показать счетчик.
Теперь, чтобы этот переход заработал, вернитесь на Main.storyboard и перетащите ваш жест касания к недавно добавленному counterViewTap(gesture:) :

Запустите. Вы увидите Graph View при запуске приложения. Позже вы сделаете Graph View скрытым для того, чтобы сначала на экране появилось представление счетчика. Нажмите на него, и вы увидите флип-переход.

Анализ Graph View

В Core Graphics изображение будет отрисовываться от заднего плана к переднему. Поэтому сначала вам нужно сформировать в голове определенный порядок элементов, а уже потом переводить его в код. Это последовательность для графика Flo:

Рисование градиента

Нарисуем градиент в представлении графика.

Откройте GraphView.swift и замените код на:

Вот что вам нужно знать из приведенного выше кода:

Откройте Main.storyboard, и вы увидите, что в представлении графика появился градиент.

В Storyboard выберите Graph View. Затем в Attributes inspector измените Start Color (цвет начала градиента) на RGB(250, 233, 222), а End Color (цвет конца градиента) на RGB (252, 79, 8). Для этого нажмите на Color, а затем на Custom:

Теперь давайте приведем все в порядок. В Main.storyboard выберите каждое представление по очереди, кроме основного, и установите значение «Clear Color» в параметр «Background Color». Вам больше не нужен желтый цвет, а все кнопки все равно будут иметь прозрачный фон.
Теперь запустите проект. Вы заметите, что график начал выглядеть намного лучше, ну или, по крайней мере обзавелся адекватным фоном.

Отсечение областей

Используя градиент, вы заполнили всю область контекста представления. Однако, если вы не хотите заполнять всю область, вы можете создать контуры для обрезки области градиента.

Теперь, в начало draw(_:) добавьте этот код:

Это создаст область отсечения, которая будет ограничивать градиент. Позже, вы будете использовать этот же прием, чтобы нарисовать второй градиент под линией графика.

Запустите и убедитесь, что у представления графика есть красивые закругленные углы:

Заметка

Если Вы используете Core Animation, вы будете использовать свойство CALayer cornerRadius вместо отсечения.

Расчет точек графика

Сделаем небольшой перерыв и займемся самим графиком. Вам нужны 7 точек. Ось X будет днями недели, а ось Y показателем выпитых стаканов воды.

Во-первых, создайте примерные данные.

Находясь в разделе GraphView.swift, в начале этого класса добавьте эти свойства:

Здесь содержатся примерные данные, которые представляют собой показания за семь дней.

Добавьте этот код в начало draw(_:) :

И вот этот код в конец draw(_:) :

Ось X состоит из 7 равноудаленных друг от друга точек. Приведенный выше код, по сути, является безымянной функцией. Его можно было бы добавить в наш проект как функцию, но для небольших вычислений, подобных этому, вы можете оставить все и в таком состоянии.

columnXPoint требует в качестве аргумента столбец и возвращает значение, в котором содержится положение точки на оси X.

Добавьте этот код для вычисления точек оси Y в конце draw(_:) :

columnYPoint также является безымянной функцией, которая берет значение из массива для дня недели в качестве параметра. Она возвращает позицию Y между 0 и наибольшим количеством выпитых стаканов.
Поскольку точка отсчета в Core Graphics находится в левом верхнем углу, а вы рисуете график из исходной точки в нижнем левом углу, функция columnYPoint корректирует возвращаемое значение, чтобы график был ориентирован в правильном направлении.
Продолжим, добавив код для рисования линии в конец draw(_:) :

Читайте также:  hacktool win32 autokms что это за вирус

Теперь, когда вы убедились, что линия рисуется правильно, удалите это из конца draw(_:) :

Это кусочек кода нужен был того, чтобы вы могли проверить строку в Storyboard и убедиться, что все расчеты верны.

Создание градиента для графика

Теперь создадим градиент под графиком, используя сам график в качестве контура для отсечения.
Сначала обозначьте контур отсечения в конце draw(_:) :

В приведенном выше коде вы:

Сейчас ваше представление графика в Storyboard`е должно выглядеть следующим образом:

Сейчас мы заменим зеленый цвет градиентом, который создадите из цветов, используемых для градиента фона.
Замените временный код в комментарии №5 этим кодом:

В этом блоке кода мы находим наибольшее количество выпитых стаканов и используем его в качестве отправной точки градиента.
Вы не можете заполнить rect тем же способом, как вы делали это с зеленым цветом. Градиент будет заполнять пространство над контекстом, а не над графиком, и желаемый градиент не будет отображаться.
Обратите внимание на комментарии к context.restoreGState() : Вы удалите их после того, как нарисуете круги вокруг точек графика.
В конце draw(_:) добавьте следующее:

Этот код рисует исходный контур.
Теперь ваш график действительно начинает обретать внешний вид:

Рисуем точки графика

В конце draw(_:) добавьте это:

В приведенном выше коде вы отрисовываете точки графика в виде заполненных круговых контуров для каждого элемента массива в вычисленных точках X и Y.

Однако, эти окружности выглядят неровными.

Рассмотрим состояние контекстов

Причина странного вида окружностей связана с контекстами. Графические контексты могут сохранять состояния. Таким образом, когда вы задаете множество свойств контекста, таких как цвет заливки, матрица преобразования, цветовое пространство или область клипа, вы фактически устанавливаете их только для текущего состояния графика.

Находитесь в GraphView.swift, в draw(_:) раскомментируйте context.saveGState() прежде чем создавать контур отсечения. Кроме того, раскомментируйте context.restoreGState() до того, как начнете его использовать.

Теперь Ваша линия графика и окружности должны выглядеть намного лучше:

В конце draw(_:) добавьте этот код, чтобы отрисовать три горизонтальные линии:

Относительно не трудно, не так ли? Вы просто двигаетесь к точке и рисуете горизонтальную линию.

Добавление меток для графика

Теперь добавим метки, чтобы сделать график более понятным.

Перейдите к ViewController.swift и добавьте следующие свойства для аутлетов:

Это добавляет аутлеты для динамического изменения текста метки average water drunk, метки max water drunk, а также меток day name стекового представления.

Теперь перейдите к Main.storyboard и добавьте следующие представления как подпредставления Graph View:

Удерживая клавишу shift, щелкните на все метки, а затем измените шрифты на пользовательский стиль Avenir Next Condensed, Medium.

Если у вас возникли проблемы с настройкой этих меток, ознакомьтесь с кодом в конечном проекте, используя кнопку «Загрузить материалы» в верхней или нижней части этого туториала.

Теперь, когда Вы закончили настройку Graph View, в Main.storyboard выберите Graph View и установите флажок Hidden, чтобы график не появлялся при первом запуске приложения.

Откройте ViewController.swift и добавьте этот метод для настройки меток:

Это выглядит немного громоздко, но Вам нужно это, чтобы настроить календарь и получить текущий день недели. Чтобы сделать это, Вы:

Запустите. Нажимаем на счетчик и видим, как график поворачивается к нам. Следовательно, все работает исправно.

Mastering the Matrix

Приложение выглядит действительно хорошо, однако, можно улучшить представление счетчика, добавив маркировку, чтобы указать каждый выпитый стакан:

Теперь, когда Вы немного попрактиковались с функциями CG, вы будете использовать их для поворота и перевода контекста чертежа.

Заметьте, что эти маркеры исходят из центра:

Помимо рисования в контексте, у Вас есть возможность манипулировать контекстом, поворачивая, масштабируя и переводя матрицу преобразования контекста.

Сначала всё это может показаться запутанным, но после того, как Вы разберете эти упражнения, Вам станет понятнее. Порядок преобразований очень важен, поэтому, вот несколько диаграмм, чтобы объяснить последовательность действий.

Следующая диаграмма является результатом поворота контекста, а затем рисования прямоугольника в его центре.

Черный прямоугольник рисуется перед поворотом контекста, за которым следуют зеленый и красный. Нужно заметить две вещи:

Когда Вы рисуете маркеры Counter View, Вы сначала переводите контекст, прежде чем его поворачивать.

На этой диаграмме маркер прямоугольника находится в самом верхнем левом углу контекста. Синие линии очерчивают переведенный контекст. Красные пунктирные линии указывают на вращение. После всего этого, Вы переводите контекст снова.

Читайте также:  при какой температуре выпекать форель

Когда Вы нарисуете красный прямоугольник в контексте, Вы заставите его появиться под углом.

После того как Вы повернете и переведете контекст, чтобы нарисовать красный маркер, Вам нужно сбросить центр, чтобы Вы могли снова повернуть и перевести контекст, и затем нарисовать зеленый маркер.

Точно так же, как Вы сохранили состояние контекста с контуром отсечения в Graph View, Вы будете сохранять и восстанавливать состояние с помощью матрицы преобразования каждый раз, когда Вы рисуете маркер.

Рисование маркеров

Используя этот код, Вы:

Хорошая работа! Теперь Вы можете восхищаться эстетичным и информативным видом интерфейса Flo:

Материалы к статье.

Источник

Seven useful methods from CGRect

Insetting, offsetting, transformation, and more!

The humble CGRect struct might seem like a primitive beast, but it has a number of useful methods that let you adjust rectangles i a variety of ways.

Here are two simple CGRect instances we can work with:

You can see that they overlap each other, and CGRect has three methods that let us evaluate that overlap. The first is the simplest: intersects() returns true if two rectangles overlap. In our case, this would be true:

If you want more details, the intersection() method tells you where the intersection lies. Both our rectangles are 100 points wide, but the second one starts at X:50 and Y:50 so that’s where our overlap will begin. So, this code will return a new CGRect containing X:50 Y:50 width:70 height:70:

The third option is the contains() method, which will return true if one rectangle entirely contains another. So, this will return false for us because the second rectangle lies partly outside the first:

For example, this will produce a rectangle at X:40 Y:40 width:60 height:60:

You’re specifying how much to grow or shrink the rectangle horizontally ( dx ) and vertically ( dy ) – these numbers apply to all four edges, which is why a horizontal change of 20 took our width from 100 to 60.

You can also make rectangles larger, like this:

I find negative insets helpful if you’re drawing behind something and want to make sure you have a fixed amount of margin on all edges.

So, this will move our rectangle 10 points down and to the right:

For more advanced transformations, you can apply any CGAffineTransform to a CGRect by calling its applying() method. You should experiment in a playground first, though – these transforms work in their own unique way.

As an example, take a look at this code:

Our rect1 constant had X:20 Y:20 width:100 height:100, so after scaling by 2x there are several possible outcomes. For example, you might think that X and Y stay the same, but width and height double, or you might think that width and height double, but X and Y go down by 50 so the rectangle stays centered.

However, what this method actually does is scale up all four coordinate components: X, Y, width, and height all double, meaning that the finished rectangle starts at X:40 Y:40 – it has been scaled relative to the top-left corner.

As an example, we could divide rect1 into two rectangles, with the first slice taking up the first 40% of rect1 and the remainder taking up everything else:

All these methods are things you could yourself, usually in a dozen lines of code or less. But do you really want to be spending your time thinking about rectangle transformations when Apple can do all that work for you? Probably not. CGRect isn’t a complex struct, but it’s worth letting it work its magic where possible!

SAVE 50% This Black Friday all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

About the author

Paul Hudson is the creator of Hacking with Swift, the most comprehensive series of Swift books in the world. He’s also the editor of Swift Developer News, the maintainer of the Swift Knowledge Base, and a speaker at Swift events around the world. If you’re curious you can learn more here.

Источник

Сказочный портал