Какао движется, перекрывая NSViews - PullRequest
0 голосов
/ 16 июля 2011

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

Что касается первой проблемы, я не нашел способа буквально увидеть, перекрываются ли два вида, если это невозможно, я подумал, может быть, нарисовав ректы на границах вида и проверив, перекрываются ли они, но я не получить, как я могу сделать любой из этих. Я думаю, что границы или рамки необходимы, но я не совсем уверен, как они отличаются.

По сути, я хочу проверить, перекрываются ли два NSView, если да, я хочу понизить один из них.

РЕДАКТИРОВАТЬ: Эта часть проблемы в значительной степени решена, но теперь возникла новая проблема. У меня есть три вида, один основной вид и два подпредставления. Главное представление не имеет ничего, оно содержит только несколько подпредставлений, то, что находится внутри основного представления, - это то, что следует видеть. Два подпредставления расположены сверху основного вида, поэтому передний виден видимым, а задний - скрытым. Когда пользователь нажимает кнопку «начало», вид сзади становится видимым, и я устанавливаю повторяющийся таймер с селектором, который проверяет, перекрываются ли представления, как сказал @Vince, если они это сделают, он немного смещается по отношению к тому, что сзади, и проверяет снова, пока они больше не пересекаются. Используя это:

- (void)updateViews {
CGRect viewFrame = [view frame]; //view is the frontmost view that will not move
CGRect backroundViewFrame = [backgroundView frame]; //the view in the back

CGRect rectIntersection = CGRectIntersection (viewFrame,
                                              backgroundFrame);

//if the intersect is NOT null, it'll offset down by 2
if (!CGRectIsNull(rectIntersection)) {
    CGRect newFrame = CGRectOffset (
                                    rectIntersection,
                                    0,     //doesn't move in x
                                    -2     //lowers by 2 in y
                                    );
    [backgroundView setFrame:newFrame]; //lowers the view to the new offset rect

} else{
    [viewsUpdater invalidate]; //stops the timer when rects no longer intersect
    viewsUpdater = nil;
}

Проблема в том, что когда я опускаю backgroundView, он виден только в том месте, где он пересекается с видом спереди. Даже если я раскрою основной вид ниже (что является идеей, все они начнутся один над другим с одинаковыми размерами, и, когда backgroundView опустится, основной вид отрегулирует и отобразит оба). Но сейчас не имеет значения, насколько велик главный вид, backgroundView виден только в той области, где он пересекается с видом спереди. Я думаю, что он движется туда, куда должен, но к тому времени, когда он останавливается, он становится полностью невидимым, поэтому я не могу сказать.

Спасибо за помощь.

1 Ответ

4 голосов
/ 16 июля 2011

По сути, вы сможете узнать, перекрываются ли два объекта NSView, получив пересечение двух свойств frame (CGRectIntersection()), а затем проверив, что результат будет нулевым, с помощью CGRectIsNull().
Вот для этого документ .

Теперь, если поместить одно представление поверх другого, звучит так, как будто вам нужно использовать этот метод из NSView: -(void)setSubviews:(NSArray *)newSubviews;, который в соответствии с документацией позволяет вам переупорядочивать подпредставления.

Или просто с помощью -(void)replaceSubview:(NSView *)oldView with:(NSView *)newView;, тем не менее, поскольку oldView будет выпущен, будьте осторожны, чтобы сохранить ссылку на него раньше.

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

CGRect actualFrame = [aView frame];
CGPoint framesOrigin = actualFrame.origin;
CGRect newFrame = CGRectMake(framesOrigin.x,
                             (framesOrigin.y)+50,
                             actualFrame.width,
                             actualFrame.height);
[aView setFrame:newFrame];

Это переместится на aView ниже, изменив координату Y начала координат своего кадра.

Наконец, о разнице между bounds и frame свойствами, этот пост на SO Разница между рамкой представления и границей представления + iPhone , должен ответить на ваш вопрос;)

...