I'm working on an application that will have a picture of guitar fretboard like on a screenshot above. There will be notes displayed in different places of fretboard (represented by red circles- there will be much more of them than on the screenshot). What kind of solution would you recommend to guarantee that the notes will be displayed in the right places of fretboard (which is just an image) and will not fall apart or distribute unevenly? Remember that the fretboard image will scale, depending on resolution, so notes positions coordinates should change accordingly.
-
just calculate the position according to the parent imageview - should be the easiest way as the fretboard is divied into same-size sectoins – longbow Mar 18 '15 at 20:40
3 Answers
If you're going to use an image that scales with the screen size, then this is one of the few cases where I would probably not use auto layout. I would create an array of doubles that would be the fraction of the distance from the left edge to the center of a particular space between the frets. So for instance, the value at index 3 (for the space where your left most red dot is) would be 0.2707 (36mm/133mm based on your image). You would then set the frame's origin.x value with that fraction times the width of the image.

- 103,982
- 12
- 207
- 218
You want to do all this in code I think and be able to activate based on fret location, string location etc... Use relative offsets for each string and fret from a known point.
This ties into your other question on SO about getting your fret image correct. Unless you can code the image accurately, then coding the note positions accurately is going to be tricky.
IMHO, you can not do this with auto layout, esp taking into account your other question: iOS autolayout - gap between image and top of the screen, despite constraints set

- 1
- 1

- 7,936
- 2
- 17
- 28
If you already managed to place the imageViews
in the right places, you could create an UIView
subclass that contains both the image and a label on top of it.
This would be my suggestion:
@interface NoteView()
@property (nonatomic, weak) UILabel *label;
@property (nonatomic, weak) UIImageView *imageView;
@end
@implementation NoteView
-(instancetype)init {
self = [super init];
if (self) {
[self setupContent];
}
return self;
}
- (void)setupContent {
UIImageView *imageView = [[UIImageView alloc] init];
[self addSubview:imageView];
[imageView setTranslatesAutoresizingMaskIntoConstraints:NO];
UILabel *label = [[UILabel alloc] init];
[self addSubview:label];
[label setTranslatesAutoresizingMaskIntoConstraints:NO];
// This adds vertical constaints between the view, the label and the imageView
// You can change the values to suit your needds
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[label]-10-[imageView]-0-|" options:0 metrics:nil views:@{ @"label": label, @"imageView": imageView }]];
// This makes the view be as big as the label
// I assumed the labels will be bigger than the images,
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[label]-0-|" options:0 metrics:nil views:@{ @"label": label}]];
// If the images are bigger use these constraints
// [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[label]-0-|" options:0 metrics:nil views:@{ @"label": label}]];
// This msakes sure that the label and the image have the same centers
[self addConstraint:[NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:imageView attribute:NSLayoutAttributeCenterX multiplier:1.f constant:0]];
[self setLabel:label];
[self setImageView:imageView];
}
// This would be a public configuration method.
- (void)setLabelText:(NSString *)text andImage:(UIImage *)image {
[self.label setText:text];
[self.imageView setImage:image];
}
@end
All you would need to do is place this custom view as you do with the images and if the frame changes call layoutIfNeeded
on the custom view so that it layouts both the image and the label correctly.
Hope this helps. Let me know if you have questions.

- 3,456
- 19
- 29