Saya perlu menggambar garis horizontal di UIView. Apa cara termudah untuk melakukannya. Misalnya, saya ingin menggambar garis horizontal hitam pada y-coord = 200.
Berikut adalah solusi lengkap & mudah untuk memiliki garis piksel tunggal dengan benar, di semua iOS, dan membuatnya mudah di storyboard: stackoverflow.com/a/26525466/294884
Fattie
Jawaban:
122
Cara termudah dalam kasus Anda (garis horizontal) adalah menambahkan subview dengan warna latar belakang hitam dan bingkai [0, 200, 320, 1].
Contoh kode (Saya harap tidak ada kesalahan - Saya menulisnya tanpa Xcode):
UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, 200, self.view.bounds.size.width, 1)];
lineView.backgroundColor = [UIColor blackColor];
[self.view addSubview:lineView];
[lineView release];
// You might also keep a reference to this view // if you are about to change its coordinates.// Just create a member and a property for this...
Cara lain adalah membuat kelas yang akan menggambar garis dalam metode drawRect (Anda dapat melihat contoh kode saya untuk ini di sini ).
Lakukan ini tanpa kode apa pun di Storyboard. Lebih mudah dan lebih baik.
coolcool1994
3
@ coolcool1994, pernahkah Anda memperhatikan "Saya TIDAK menggunakan Interface Builder." persyaratan dalam pertanyaan?
Michael Kessler
312
Mungkin ini agak terlambat, tapi saya ingin menambahkan bahwa ada cara yang lebih baik. Menggunakan UIView sederhana, tetapi relatif lambat. Metode ini menimpa cara menggambar dirinya sendiri dan lebih cepat:
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
// Draw them with a 2.0 stroke width so they are a bit more visible.CGContextSetLineWidth(context, 2.0f);
CGContextMoveToPoint(context, 0.0f, 0.0f); //start at this pointCGContextAddLineToPoint(context, 20.0f, 20.0f); //draw to this point// and now draw the Path!CGContextStrokePath(context);
}
Jika kode ini digunakan dalam UIView, apakah koordinat dalam sampel ini relatif terhadap batas tampilan atau seluruh layar?
ChrisP
Apakah seseorang tidak perlu menelepon CGContextBeginPath(context);sebelumnya CGContextMoveToPoint(...);?
i_am_jorf
37
Menggunakan pandangan untuk melakukannya tidak terlalu buruk. Itu membuat segalanya lebih mudah, misalnya, saat melakukan animasi implisit selama perubahan orientasi. Jika hanya satu, UIView lain tidak terlalu mahal dan kodenya jauh lebih sederhana.
i_am_jorf
Selain itu, Anda bisa mendapatkan batas dan titik tengah dengan kode ini: CGPoint midpoint; midPoint.x = self.bounds.size.width / 2; midPoint.y = self.bounds.size.height / 2;
coolcool1994
1
Benar, komentar bahwa itu "lambat" tidak masuk akal. Ada banyak UIViews sederhana di layar setiap saat. Perhatikan bahwa menggambar karakter teks SATU (!), Dengan semua proses yang terlibat, rawa menggambar UIView yang terisi.
Fattie
30
Swift 3 dan Swift 4
Ini adalah bagaimana Anda bisa menggambar garis abu-abu di akhir tampilan Anda (ide yang sama seperti jawaban b123400)
"Jika biarkan konteks" gagal saat dipanggil dari viewDidLayoutSubviews.
Oscar
14
Cukup tambahkan Label tanpa teks dan dengan warna latar belakang. Atur Koordinat pilihan Anda dan juga tinggi dan lebar. Anda dapat melakukannya secara manual atau dengan Interface Builder.
Dan menginisialisasi objek pathArray dan dictPAth yang akan digunakan untuk menggambar garis. Saya menulis bagian utama kode dari proyek saya sendiri:
- (void)drawRect:(CGRect)rect
{
for(NSDictionary *_pathDict in pathArray)
{
[((UIColor *)[_pathDict valueForKey:@"color"]) setStroke]; // this method will choose the color from the receiver color object (in this case this object is :strokeColor)[[_pathDict valueForKey:@"path"]strokeWithBlendMode:kCGBlendModeNormalalpha:1.0];
}
[[dict_path objectForKey:@"color"]setStroke]; // this method will choose the color from the receiver color object (in this case this object is :strokeColor)[[dict_path objectForKey:@"path"]strokeWithBlendMode:kCGBlendModeNormalalpha:1.0];
}
Jawaban:
Cara termudah dalam kasus Anda (garis horizontal) adalah menambahkan subview dengan warna latar belakang hitam dan bingkai
[0, 200, 320, 1]
.Contoh kode (Saya harap tidak ada kesalahan - Saya menulisnya tanpa Xcode):
UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, 200, self.view.bounds.size.width, 1)]; lineView.backgroundColor = [UIColor blackColor]; [self.view addSubview:lineView]; [lineView release]; // You might also keep a reference to this view // if you are about to change its coordinates. // Just create a member and a property for this...
Cara lain adalah membuat kelas yang akan menggambar garis dalam metode drawRect (Anda dapat melihat contoh kode saya untuk ini di sini ).
sumber
Mungkin ini agak terlambat, tapi saya ingin menambahkan bahwa ada cara yang lebih baik. Menggunakan UIView sederhana, tetapi relatif lambat. Metode ini menimpa cara menggambar dirinya sendiri dan lebih cepat:
- (void)drawRect:(CGRect)rect { [super drawRect:rect]; CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor); // Draw them with a 2.0 stroke width so they are a bit more visible. CGContextSetLineWidth(context, 2.0f); CGContextMoveToPoint(context, 0.0f, 0.0f); //start at this point CGContextAddLineToPoint(context, 20.0f, 20.0f); //draw to this point // and now draw the Path! CGContextStrokePath(context); }
sumber
CGContextBeginPath(context);
sebelumnyaCGContextMoveToPoint(...);
?Swift 3 dan Swift 4
Ini adalah bagaimana Anda bisa menggambar garis abu-abu di akhir tampilan Anda (ide yang sama seperti jawaban b123400)
class CustomView: UIView { override func draw(_ rect: CGRect) { super.draw(rect) if let context = UIGraphicsGetCurrentContext() { context.setStrokeColor(UIColor.gray.cgColor) context.setLineWidth(1) context.move(to: CGPoint(x: 0, y: bounds.height)) context.addLine(to: CGPoint(x: bounds.width, y: bounds.height)) context.strokePath() } } }
sumber
Cukup tambahkan Label tanpa teks dan dengan warna latar belakang. Atur Koordinat pilihan Anda dan juga tinggi dan lebar. Anda dapat melakukannya secara manual atau dengan Interface Builder.
sumber
Anda dapat menggunakan UIBezierPath Class untuk ini:
Dan dapat menggambar garis sebanyak yang Anda inginkan:
Saya telah membuat subclass UIView:
@interface MyLineDrawingView() { NSMutableArray *pathArray; NSMutableDictionary *dict_path; CGPoint startPoint, endPoint; } @property (nonatomic,retain) UIBezierPath *myPath; @end
Dan menginisialisasi objek pathArray dan dictPAth yang akan digunakan untuk menggambar garis. Saya menulis bagian utama kode dari proyek saya sendiri:
- (void)drawRect:(CGRect)rect { for(NSDictionary *_pathDict in pathArray) { [((UIColor *)[_pathDict valueForKey:@"color"]) setStroke]; // this method will choose the color from the receiver color object (in this case this object is :strokeColor) [[_pathDict valueForKey:@"path"] strokeWithBlendMode:kCGBlendModeNormal alpha:1.0]; } [[dict_path objectForKey:@"color"] setStroke]; // this method will choose the color from the receiver color object (in this case this object is :strokeColor) [[dict_path objectForKey:@"path"] strokeWithBlendMode:kCGBlendModeNormal alpha:1.0]; }
metode touchesBegin:
UITouch *touch = [touches anyObject]; startPoint = [touch locationInView:self]; myPath=[[UIBezierPath alloc]init]; myPath.lineWidth = currentSliderValue*2; dict_path = [[NSMutableDictionary alloc] init];
touchesMoved Method:
UITouch *touch = [touches anyObject]; endPoint = [touch locationInView:self]; [myPath removeAllPoints]; [dict_path removeAllObjects];// remove prev object in dict (this dict is used for current drawing, All past drawings are managed by pathArry) // actual drawing [myPath moveToPoint:startPoint]; [myPath addLineToPoint:endPoint]; [dict_path setValue:myPath forKey:@"path"]; [dict_path setValue:strokeColor forKey:@"color"]; // NSDictionary *tempDict = [NSDictionary dictionaryWithDictionary:dict_path]; // [pathArray addObject:tempDict]; // [dict_path removeAllObjects]; [self setNeedsDisplay];
Metode touchesEnded:
NSDictionary *tempDict = [NSDictionary dictionaryWithDictionary:dict_path]; [pathArray addObject:tempDict]; [dict_path removeAllObjects]; [self setNeedsDisplay];
sumber
Satu kemungkinan lainnya (dan bahkan lebih pendek). Jika Anda berada di dalam drawRect, seperti berikut ini:
[[UIColor blackColor] setFill]; UIRectFill((CGRect){0,200,rect.size.width,1});
sumber
Berdasarkan jawaban Guy Daher.
Saya mencoba untuk menghindari penggunaan? karena bisa menyebabkan aplikasi macet jika GetCurrentContext () mengembalikan nihil.
Saya tidak akan memeriksa jika pernyataan:
class CustomView: UIView { override func draw(_ rect: CGRect) { super.draw(rect) if let context = UIGraphicsGetCurrentContext() { context.setStrokeColor(UIColor.gray.cgColor) context.setLineWidth(1) context.move(to: CGPoint(x: 0, y: bounds.height)) context.addLine(to: CGPoint(x: bounds.width, y: bounds.height)) context.strokePath() } } }
sumber
if
klausa hanya untuk melepas kotak dari opsional, lebih baik gunakanguard
pernyataan sebagai gantinya.Tambahkan label tanpa teks dan dengan warna latar belakang sesuai ukuran frame (misal: tinggi = 1). Lakukan melalui kode atau di pembuat antarmuka.
sumber