Неправильное расположение подвидов

Я хочу расположить несколько пользовательских NSView один за другим. Но когда я запускаю приложение, представления рисуются с другими (удвоенными) значениями начала кадра, чем значения, установленные в коде.

Вот упрощенный код с двумя представлениями:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application 

float height1 = 40.0;
float height2 = 65.0;

float width = [[window contentView] frame].size.width;

NSRect r1 = NSMakeRect(0, 0, width, height1);
NSRect r2 = NSMakeRect(0, height1, width, height2);

MyView *c1 = [[MyView alloc] initWithFrame:r1];
MyView *c2 = [[MyView alloc] initWithFrame:r2];

[[window contentView] addSubview:c1];
[[window contentView] addSubview:c2];
}

код для MyView в основном состоит только из drawRect:

- (void)drawRect:(NSRect)dirtyRect {
// Drawing code here.

NSRect cellFrame = [self frame];

// frame Y coordinates at superview
float superY = [self convertPoint:[self frame].origin 
                      toView:[self superview]].y;

NSLog(@"superY:%f selfY:%f", superY, cellFrame.origin.y);


// top, bottom border and diagonal line of [self frame]
NSBezierPath* borderLine = [NSBezierPath bezierPath];

NSPoint pt1 = NSMakePoint(cellFrame.origin.x, 
                          cellFrame.origin.y);
NSPoint pt2 = NSMakePoint(cellFrame.origin.x + cellFrame.size.width,
                          cellFrame.origin.y);
NSPoint pt3 = NSMakePoint(cellFrame.origin.x,
                          cellFrame.origin.y + cellFrame.size.height);
NSPoint pt4 = NSMakePoint(cellFrame.origin.x + cellFrame.size.width,
                          cellFrame.origin.y + cellFrame.size.height);

[borderLine moveToPoint:pt1];
[borderLine lineToPoint:pt2];
[borderLine lineToPoint:pt3];
[borderLine lineToPoint:pt4];

[[NSColor redColor] setStroke];
[borderLine setLineWidth:01];
[borderLine stroke];
} 

и вот результат (как видите - координата y второго вида удвоена и по какой-то причине этот вид нарисован только частично):

результат с консолью


person platlas    schedule 22.10.2011    source источник


Ответы (1)


Вы смешиваете концепцию прямоугольников рамки и границ представления. «Границы» относятся к размерам представления в его собственной системе координат, т.е. начало координат будет равно нулю, а размер будет шириной и высотой представления.

«Рамка» относится к размерам представления в системе координат его родительского представления, т. е. начало координат будет везде, где представление расположено в его суперпредставлении, а ширина и высота будут такими же, как у прямоугольника границ.

Таким образом, для регистрации в вашем примере кода вы вызываете «convertPoint» без необходимости и неправильно, потому что вы можете получить фактическое происхождение представления, просто вызвав «[self frame].origin»

При рисовании вам нужно вызвать «[selfbounds]», чтобы получить прямоугольник, в котором нужно рисовать. В своем коде вы вызываете «[self frame]», который дает вам прямоугольник в системе координат вашего супервизора (кадре), но это не будет работать, потому что процедуры рисования рисуют в собственной системе координат (границы) вида (т.е. с исходной в {0, 0})

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

Я заставил ваш код работать, изменив

NSRect cellFrame = [self frame];

to

NSRect cellFrame = [self bounds];

Кроме того, самый простой способ зарегистрировать NSRect —

NSLog(@"%@", NSStringFromRect([self frame])); например.

Надеюсь, это поможет.

person Francis McGrew    schedule 23.10.2011