Cocoa NSTableView, NSTextFieldCell, NSCell, ImageAndTextCell tutorial
2013-10-27 10:11
477 查看
http://juliuspaintings.co.uk/cgi-bin/paint_css/animatedPaint/070-NSTableView-ImageAndTextCell.pl
Problem: We want to display a table of rows of text and image pairs. NSTableView looks like the ideal display context but there is no specific NSCell type dedicated to this kind
Answer: We make use of Apple's ImageAndTextCell Class that is to be found in Apple's SourceView
The key idea is straightforward. Subclass NSTextViewCell as the class ImageAndText (Apple example: ImageAndTextCell.h,ImageAndTextCell.m).
This class will intercept the call to NSTextViewCell's drawWithFrame:inView: method and use it to draw the image before passing control on to super' drawWithFrame:inView: which will draw the text.
One thing to remember is that the same ImageAndText object is used to display each of the text and image pairs. Essentially one can think of ImageAndText being moved through successive rows drawing as it goes.
In Interface Builder declare your control to be both the NSTableView's delegate and data source.
As delegate declare methods for:
the obligatory pair of -(NSInteger)numberOfRowsInTableView:,
and -(id)tableView:objectValueForTableColumn:row:
Then the method for putting the data into the cell
-(void)tableView:willDisplayCell:forTableColumn:row:
and that for putting the returned edited text back into the database
-(void)tableView:setObjectValue:forTableColumn:row:
For reasons I have yet to determine one also needs to declare
- (NSCell *)tableView:dataCellForTableColumn:row:
tell NSTableView to stop editing or the edit will appear in the newly inserted row.
The only approach I've so far found to work was presented inhttp://www.stone.com/The_Cocoa_Files/Takes_All_Sorts.html.
This consists of returning focus to the NSTableView window. See the addAtSelectedRow method below. This preserves the original edit. To abort the edit completely use the NSTableView method abortEditing.
// ImageAndTextCell.h
//
// Copyright 2006, Apple. All rights reserved.
// JJG: edited to remove memory management statements
// and for this example inessential code.
#import <Cocoa/Cocoa.h>
@interface ImageAndTextCell : NSTextFieldCell {
@private
NSImage*nsImageObj;
}
@property (assign) NSImage*nsImageObj;
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView;
//- (NSSize)cellSize;
@end
// ImageAndTextCell.m
// Copyright 2006, Apple Computer, Inc., all rights reserved.
//
// Subclass of NSTextFieldCell which can display text
// and an image simultaneously.
// JJG: edited to remove memory management statements
// and for this example inessential code.
#import "ImageAndTextCell.h"
@implementation ImageAndTextCell
@synthesize nsImageObj;
- (id)copyWithZone:(NSZone *)zone {
ImageAndTextCell *zCell = (ImageAndTextCell *)[super copyWithZone:zone];
zCell.nsImageObj =self.nsImageObj;
return zCell;
} // end copyWithZone
// over-ride NSCell selectWithFrame :
// called when frame is selected for editing
- (void)selectWithFrame:(NSRect)aRect
inView:(NSView *)controlView
editor:(NSText *)textObj
delegate:(id)anObject
start:(NSInteger)selStart
length:(NSInteger)selLength {
NSLog(@"My Cell: selectWithFrame");
NSRect textFrame, imageFrame;
NSDivideRect (aRect, &imageFrame,&textFrame,
3+[nsImageObj size].width,NSMinXEdge);
[super selectWithFrame: textFrame
inView: controlView
editor:textObj
delegate:anObject
start:selStart
length:selLength];
}
// draw the image on the left hand side of the NSTextFieldCell
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
if (nsImageObj ==
nil) {
[super drawWithFrame:cellFrame inView:controlView];
return;
}// end if
NSSizeimageSize;
NSRectimageFrame;
//NSRecttextFrame;
imageSize = [nsImageObj size];
NSDivideRect(cellFrame,&imageFrame,&cellFrame,
3+imageSize.width,NSMinXEdge);
if ([self drawsBackground]){
[[self backgroundColor] set];
NSRectFill(imageFrame);
}// end if
imageFrame.origin.x +=3;
imageFrame.size = imageSize;
if ([controlView isFlipped]) {
imageFrame.origin.y += ceil((cellFrame.size.height+
imageFrame.size.height)/2);
}else {
imageFrame.origin.y += ceil((cellFrame.size.height-
imageFrame.size.height)/2);
}// end if
[nsImageObj compositeToPoint:imageFrame.origin
operation:NSCompositeSourceOver];
[super drawWithFrame:cellFrame inView:controlView];
//[super drawWithFrame:textFrame inView:controlView];
}
@end
//
// MyController.h
// TableViewExample
#import
//@class MyNSCell;
@class ImageAndTextCell;
@interface MyController : NSObject {
NSMutableArray * nsMutaryOfMyData;
ImageAndTextCell * myImageAndTextCelObj;
IBOutlet NSTableView * nsTableViewObj;
}
@property (assign) NSMutableArray * nsMutaryOfMyData;
@property (assign) ImageAndTextCell * myImageAndTextCelObj;
@property (assign)
IBOutlet NSTableView * nsTableViewObj;
//- (IBAction)tableViewSelected:(id)sender;
- (IBAction)addAtSelectedRow:(id)pId;
- (IBAction)addToEndOfTable:(id)pId;
- (IBAction)removeCellAtSelectedRow:(id)sender;
@end
//
// MyController.m
// TableViewExample
#import "MyController.h"
#import "MyData.h"
#import "ImageAndTextCell.h"
@implementation MyController
@synthesize nsMutaryOfMyData;
@synthesize nsTableViewObj;
@synthesize myImageAndTextCelObj;
//@synthesize nsIntSelectedRow;
// first step
// cashe the images in MyData
// second step : get the add abd delete going
- (void) awakeFromNib {
//
self.nsIntSelectedRow = -1;
self.nsMutaryOfMyData = [[NSMutableArray alloc]init];
[self.nsMutaryOfMyData addObject:[[MyData alloc]
initWithImagePathString:@"../../../Lucia.tif"
text:@"Lucia, dog, peacock and Galapagos turtle"]];
[self.nsMutaryOfMyData addObject:[[MyData alloc]
initWithImagePathString:@"../../../BellaSeals.tif"
text:@"Bella's Dream (detail): Bella, Lucia and seals"]];
[self.nsMutaryOfMyData addObject:[[MyData alloc]
initWithImagePathString:@"../../../BellaPanda.tif"
text:@"Bella's Dream (detail): Bella, Lucia and Panda"]];
[self.nsMutaryOfMyData addObject:[[MyData alloc]
initWithImagePathString:@"../../../danceOfLife.tif"
text:@"Stuff That Stars Are Made Of (detail): Dance of Life"]];
[self.nsMutaryOfMyData addObject:[[MyData alloc]
initWithImagePathString:@"../../../landBogay.tif"
text:@"View of Bogay"]];
[self.nsMutaryOfMyData addObject:[[MyData alloc]
initWithImagePathString:@"../../../landRiverRoeSpring.tif"
text:@"The River Roe in Spring"]];
[self.nsMutaryOfMyData addObject:[[MyData alloc]
initWithImagePathString:@"../../../oliveHarvest.tif"
text:@"The Olive Harvest"]];
self.myImageAndTextCelObj = [[ImageAndTextCell alloc] init];
self.myImageAndTextCelObj.image =
[self.nsMutaryOfMyData objectAtIndex:0]nsImageObj];
[self.myImageAndTextCelObj setEditable:YES];
NSTableColumn* zTableColumnObj =
[[self.nsTableViewObj tableColumns] objectAtIndex:0];
[zTableColumnObj setDataCell:self.myImageAndTextCelObj];
} // end awakeFromNib
// these are called by the table(s)
- (NSInteger)numberOfRowsInTableView:(NSTableView *)pTableView
{
return [nsMutaryOfMyData count];
} // end numberOfRowsInTableView
- (id)tableView:(NSTableView *)pTableView
objectValueForTableColumn:(NSTableColumn *)pTableColumn
row:(int)pRow {
MyData * zMyDataObj= [self.nsMutaryOfMyData objectAtIndex:pRow];
return zMyDataObj.nsStrText;
// Note if returned string is same as that typed into the cell
// then no update takes place
// e.g. returned string="fred", cell = "hello world",
// user selects the word "world" and types "fred": no change takes place.
} // end tableView:objectValueForTableColumn:tableColumn
// this is the delegate method that allows you to put data into your cell
- (void)tableView:(NSTableView *)tableView
willDisplayCell:(id)cell
forTableColumn:(NSTableColumn *)tableColumn
row:(NSInteger)pRow {
//NSLog(@"willDisplayCell");
MyData * zMyDataObj= [self.nsMutaryOfMyData objectAtIndex:pRow];
ImageAndTextCell * zMyCell= (ImageAndTextCell *)cell;
zMyCell.nsImageObj= zMyDataObj.nsImageObj;
[zMyCell setTitle:zMyDataObj.nsStrText];
} // end tableView:willDisplayCell:forTableColumn:row:
// this is the routine that returns cell data (an edited string)
// back after editing
- (void)tableView:(NSTableView *)aTableView
setObjectValue:anObject
forTableColumn:(NSTableColumn *)aTableColumn
row:(NSInteger)pRow {
MyData * zMyDataObj= [self.nsMutaryOfMyData objectAtIndex:pRow];
NSLog(@"setObjectValue string = %@",(NSString *)anObject);
zMyDataObj.nsStrText= (NSString *)anObject;
} // end tableView:setObjectValue:forTableColumn:row:
// if this is not here we crash - called whenever mouseOver
- (NSCell *)tableView:(NSTableView *)pTableView
dataCellForTableColumn:(NSTableColumn *)pTableColumn
row:(NSInteger)pRow {
//NSLog(@"dataCellForTableColumn");
returnself.myImageAndTextCelObj;
} // end tableView:dataCellForTableColumn:row:
//- (IBAction)tableViewSelected:(id)sender {
// NSLog(@"the user just clicked on row %d",
// [self.nsTableViewObj selectedRow]);
//} // end tableViewSelected
- (IBAction)addAtSelectedRow:(id)pId {
NSLog(@"addAtSelectedRow");
// this ends the editing if an edit was begun
// just before the addAtSelectedRow button was clicked.
[[self.nsTableViewObjwindow]makeFirstResponder:[self.nsTableViewObjwindow]];
NSInteger zSelectedRow= [self.nsTableViewObj selectedRow];
if ( zSelectedRow <
0) {
return;
}// end if
NSParameterAssert(zSelectedRow < [self.nsMutaryOfMyData count]);// crash
[nsMutaryOfMyData insertObject:[[MyData alloc]
initWithImagePathString:@"../../../anghiari.tif"
text:@"Copy after Ruben's copy after Leonardo:
The Battle of Anghiari..
And here is some extra text to see how we get on
with very lengthy things"]
atIndex:zSelectedRow];
[self.nsTableViewObj noteNumberOfRowsChanged];
[self.nsTableViewObj reloadData];
} // end addAtSelectedRow
- (IBAction)addToEndOfTable:(id)pId {
NSLog(@"addToEndOfTable");
[nsMutaryOfMyData addObject:[[MyData alloc]
initWithImagePathString:@"../../../BellaElephants.tif"
text:@"Bella's Dream (detail): Bella and Elephants"]];
[self.nsTableViewObj noteNumberOfRowsChanged];
[self.nsTableViewObj reloadData];
} // end addToEndOfTable
- (IBAction)removeCellAtSelectedRow:(id)sender {
if ([self.nsTableViewObj selectedRow] <0 ||
[self.nsTableViewObj selectedRow] >= [nsMutaryOfMyData count]) {
return;
}// end if
[nsMutaryOfMyData removeObjectAtIndex:[self.nsTableViewObj selectedRow]];
[self.nsTableViewObj noteNumberOfRowsChanged];
[self.nsTableViewObj reloadData];
} // end removeCellAtSelectedRow
@end
//
// MyData.h
// TableViewExample
#import
@interface MyData : NSObject {
NSString * nsStrText;
NSImage * nsImageObj;
}
@property (assign) NSString * nsStrText;
@property (assign) NSImage * nsImageObj;
- (id) initWithImagePathString:(NSString *)pImagePath
text:(NSString *)pText;
@end
//
// MyData.m
// TableViewExample
//
#import "MyData.h"
@implementation MyData
@synthesize nsStrText;
@synthesize nsImageObj;
- (id) initWithImagePathString:(NSString *)pImagePath
text:(NSString *)pText {
if (! (self = [super init])) {
NSLog(@"*Error* MyData initWithImagePathString");
return
self;
}// end if
self.nsStrText = pText;
self.nsImageObj
= [[NSImage alloc] initWithContentsOfFile:pImagePath];
return
self;
}// end initWithImagePathString
@end
70: Display an NSTextfieldCell containing text and an image within a NSTableView
Problem: We want to display a table of rows of text and image pairs. NSTableView looks like the ideal display context but there is no specific NSCell type dedicated to this kind
of task. The text is to be editable and the means provided for the user to delete a selected row, insert a new row at a selected row or at table end
Example NSTableView using NSTextFieldCell and ImageAndTextCell
Answer: We make use of Apple's ImageAndTextCell Class that is to be found in Apple's SourceView
example.
The key idea is straightforward. Subclass NSTextViewCell as the class ImageAndText (Apple example: ImageAndTextCell.h,ImageAndTextCell.m).This class will intercept the call to NSTextViewCell's drawWithFrame:inView: method and use it to draw the image before passing control on to super' drawWithFrame:inView: which will draw the text.
One thing to remember is that the same ImageAndText object is used to display each of the text and image pairs. Essentially one can think of ImageAndText being moved through successive rows drawing as it goes.
In Interface Builder declare your control to be both the NSTableView's delegate and data source.
As delegate declare methods for:
the obligatory pair of -(NSInteger)numberOfRowsInTableView:,
and -(id)tableView:objectValueForTableColumn:row:
Then the method for putting the data into the cell
-(void)tableView:willDisplayCell:forTableColumn:row:
and that for putting the returned edited text back into the database
-(void)tableView:setObjectValue:forTableColumn:row:
For reasons I have yet to determine one also needs to declare
- (NSCell *)tableView:dataCellForTableColumn:row:
A curiosity
There are occasions on which one needs to tell NSTableView to end editing. For instance, if one has clicked on the text in one of the rows and started editing and then without doing anything else one clicks on the AddAtSelectedRow key, it is necesary totell NSTableView to stop editing or the edit will appear in the newly inserted row.
The only approach I've so far found to work was presented inhttp://www.stone.com/The_Cocoa_Files/Takes_All_Sorts.html.
This consists of returning focus to the NSTableView window. See the addAtSelectedRow method below. This preserves the original edit. To abort the edit completely use the NSTableView method abortEditing.
Source code
//// ImageAndTextCell.h
//
// Copyright 2006, Apple. All rights reserved.
// JJG: edited to remove memory management statements
// and for this example inessential code.
#import <Cocoa/Cocoa.h>
@interface ImageAndTextCell : NSTextFieldCell {
@private
NSImage*nsImageObj;
}
@property (assign) NSImage*nsImageObj;
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView;
//- (NSSize)cellSize;
@end
// ImageAndTextCell.m
// Copyright 2006, Apple Computer, Inc., all rights reserved.
//
// Subclass of NSTextFieldCell which can display text
// and an image simultaneously.
// JJG: edited to remove memory management statements
// and for this example inessential code.
#import "ImageAndTextCell.h"
@implementation ImageAndTextCell
@synthesize nsImageObj;
- (id)copyWithZone:(NSZone *)zone {
ImageAndTextCell *zCell = (ImageAndTextCell *)[super copyWithZone:zone];
zCell.nsImageObj =self.nsImageObj;
return zCell;
} // end copyWithZone
// over-ride NSCell selectWithFrame :
// called when frame is selected for editing
- (void)selectWithFrame:(NSRect)aRect
inView:(NSView *)controlView
editor:(NSText *)textObj
delegate:(id)anObject
start:(NSInteger)selStart
length:(NSInteger)selLength {
NSLog(@"My Cell: selectWithFrame");
NSRect textFrame, imageFrame;
NSDivideRect (aRect, &imageFrame,&textFrame,
3+[nsImageObj size].width,NSMinXEdge);
[super selectWithFrame: textFrame
inView: controlView
editor:textObj
delegate:anObject
start:selStart
length:selLength];
}
// draw the image on the left hand side of the NSTextFieldCell
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
if (nsImageObj ==
nil) {
[super drawWithFrame:cellFrame inView:controlView];
return;
}// end if
NSSizeimageSize;
NSRectimageFrame;
//NSRecttextFrame;
imageSize = [nsImageObj size];
NSDivideRect(cellFrame,&imageFrame,&cellFrame,
3+imageSize.width,NSMinXEdge);
if ([self drawsBackground]){
[[self backgroundColor] set];
NSRectFill(imageFrame);
}// end if
imageFrame.origin.x +=3;
imageFrame.size = imageSize;
if ([controlView isFlipped]) {
imageFrame.origin.y += ceil((cellFrame.size.height+
imageFrame.size.height)/2);
}else {
imageFrame.origin.y += ceil((cellFrame.size.height-
imageFrame.size.height)/2);
}// end if
[nsImageObj compositeToPoint:imageFrame.origin
operation:NSCompositeSourceOver];
[super drawWithFrame:cellFrame inView:controlView];
//[super drawWithFrame:textFrame inView:controlView];
}
@end
//
// MyController.h
// TableViewExample
#import
//@class MyNSCell;
@class ImageAndTextCell;
@interface MyController : NSObject {
NSMutableArray * nsMutaryOfMyData;
ImageAndTextCell * myImageAndTextCelObj;
IBOutlet NSTableView * nsTableViewObj;
}
@property (assign) NSMutableArray * nsMutaryOfMyData;
@property (assign) ImageAndTextCell * myImageAndTextCelObj;
@property (assign)
IBOutlet NSTableView * nsTableViewObj;
//- (IBAction)tableViewSelected:(id)sender;
- (IBAction)addAtSelectedRow:(id)pId;
- (IBAction)addToEndOfTable:(id)pId;
- (IBAction)removeCellAtSelectedRow:(id)sender;
@end
//
// MyController.m
// TableViewExample
#import "MyController.h"
#import "MyData.h"
#import "ImageAndTextCell.h"
@implementation MyController
@synthesize nsMutaryOfMyData;
@synthesize nsTableViewObj;
@synthesize myImageAndTextCelObj;
//@synthesize nsIntSelectedRow;
// first step
// cashe the images in MyData
// second step : get the add abd delete going
- (void) awakeFromNib {
//
self.nsIntSelectedRow = -1;
self.nsMutaryOfMyData = [[NSMutableArray alloc]init];
[self.nsMutaryOfMyData addObject:[[MyData alloc]
initWithImagePathString:@"../../../Lucia.tif"
text:@"Lucia, dog, peacock and Galapagos turtle"]];
[self.nsMutaryOfMyData addObject:[[MyData alloc]
initWithImagePathString:@"../../../BellaSeals.tif"
text:@"Bella's Dream (detail): Bella, Lucia and seals"]];
[self.nsMutaryOfMyData addObject:[[MyData alloc]
initWithImagePathString:@"../../../BellaPanda.tif"
text:@"Bella's Dream (detail): Bella, Lucia and Panda"]];
[self.nsMutaryOfMyData addObject:[[MyData alloc]
initWithImagePathString:@"../../../danceOfLife.tif"
text:@"Stuff That Stars Are Made Of (detail): Dance of Life"]];
[self.nsMutaryOfMyData addObject:[[MyData alloc]
initWithImagePathString:@"../../../landBogay.tif"
text:@"View of Bogay"]];
[self.nsMutaryOfMyData addObject:[[MyData alloc]
initWithImagePathString:@"../../../landRiverRoeSpring.tif"
text:@"The River Roe in Spring"]];
[self.nsMutaryOfMyData addObject:[[MyData alloc]
initWithImagePathString:@"../../../oliveHarvest.tif"
text:@"The Olive Harvest"]];
self.myImageAndTextCelObj = [[ImageAndTextCell alloc] init];
self.myImageAndTextCelObj.image =
[self.nsMutaryOfMyData objectAtIndex:0]nsImageObj];
[self.myImageAndTextCelObj setEditable:YES];
NSTableColumn* zTableColumnObj =
[[self.nsTableViewObj tableColumns] objectAtIndex:0];
[zTableColumnObj setDataCell:self.myImageAndTextCelObj];
} // end awakeFromNib
// these are called by the table(s)
- (NSInteger)numberOfRowsInTableView:(NSTableView *)pTableView
{
return [nsMutaryOfMyData count];
} // end numberOfRowsInTableView
- (id)tableView:(NSTableView *)pTableView
objectValueForTableColumn:(NSTableColumn *)pTableColumn
row:(int)pRow {
MyData * zMyDataObj= [self.nsMutaryOfMyData objectAtIndex:pRow];
return zMyDataObj.nsStrText;
// Note if returned string is same as that typed into the cell
// then no update takes place
// e.g. returned string="fred", cell = "hello world",
// user selects the word "world" and types "fred": no change takes place.
} // end tableView:objectValueForTableColumn:tableColumn
// this is the delegate method that allows you to put data into your cell
- (void)tableView:(NSTableView *)tableView
willDisplayCell:(id)cell
forTableColumn:(NSTableColumn *)tableColumn
row:(NSInteger)pRow {
//NSLog(@"willDisplayCell");
MyData * zMyDataObj= [self.nsMutaryOfMyData objectAtIndex:pRow];
ImageAndTextCell * zMyCell= (ImageAndTextCell *)cell;
zMyCell.nsImageObj= zMyDataObj.nsImageObj;
[zMyCell setTitle:zMyDataObj.nsStrText];
} // end tableView:willDisplayCell:forTableColumn:row:
// this is the routine that returns cell data (an edited string)
// back after editing
- (void)tableView:(NSTableView *)aTableView
setObjectValue:anObject
forTableColumn:(NSTableColumn *)aTableColumn
row:(NSInteger)pRow {
MyData * zMyDataObj= [self.nsMutaryOfMyData objectAtIndex:pRow];
NSLog(@"setObjectValue string = %@",(NSString *)anObject);
zMyDataObj.nsStrText= (NSString *)anObject;
} // end tableView:setObjectValue:forTableColumn:row:
// if this is not here we crash - called whenever mouseOver
- (NSCell *)tableView:(NSTableView *)pTableView
dataCellForTableColumn:(NSTableColumn *)pTableColumn
row:(NSInteger)pRow {
//NSLog(@"dataCellForTableColumn");
returnself.myImageAndTextCelObj;
} // end tableView:dataCellForTableColumn:row:
//- (IBAction)tableViewSelected:(id)sender {
// NSLog(@"the user just clicked on row %d",
// [self.nsTableViewObj selectedRow]);
//} // end tableViewSelected
- (IBAction)addAtSelectedRow:(id)pId {
NSLog(@"addAtSelectedRow");
// this ends the editing if an edit was begun
// just before the addAtSelectedRow button was clicked.
[[self.nsTableViewObjwindow]makeFirstResponder:[self.nsTableViewObjwindow]];
NSInteger zSelectedRow= [self.nsTableViewObj selectedRow];
if ( zSelectedRow <
0) {
return;
}// end if
NSParameterAssert(zSelectedRow < [self.nsMutaryOfMyData count]);// crash
[nsMutaryOfMyData insertObject:[[MyData alloc]
initWithImagePathString:@"../../../anghiari.tif"
text:@"Copy after Ruben's copy after Leonardo:
The Battle of Anghiari..
And here is some extra text to see how we get on
with very lengthy things"]
atIndex:zSelectedRow];
[self.nsTableViewObj noteNumberOfRowsChanged];
[self.nsTableViewObj reloadData];
} // end addAtSelectedRow
- (IBAction)addToEndOfTable:(id)pId {
NSLog(@"addToEndOfTable");
[nsMutaryOfMyData addObject:[[MyData alloc]
initWithImagePathString:@"../../../BellaElephants.tif"
text:@"Bella's Dream (detail): Bella and Elephants"]];
[self.nsTableViewObj noteNumberOfRowsChanged];
[self.nsTableViewObj reloadData];
} // end addToEndOfTable
- (IBAction)removeCellAtSelectedRow:(id)sender {
if ([self.nsTableViewObj selectedRow] <0 ||
[self.nsTableViewObj selectedRow] >= [nsMutaryOfMyData count]) {
return;
}// end if
[nsMutaryOfMyData removeObjectAtIndex:[self.nsTableViewObj selectedRow]];
[self.nsTableViewObj noteNumberOfRowsChanged];
[self.nsTableViewObj reloadData];
} // end removeCellAtSelectedRow
@end
//
// MyData.h
// TableViewExample
#import
@interface MyData : NSObject {
NSString * nsStrText;
NSImage * nsImageObj;
}
@property (assign) NSString * nsStrText;
@property (assign) NSImage * nsImageObj;
- (id) initWithImagePathString:(NSString *)pImagePath
text:(NSString *)pText;
@end
//
// MyData.m
// TableViewExample
//
#import "MyData.h"
@implementation MyData
@synthesize nsStrText;
@synthesize nsImageObj;
- (id) initWithImagePathString:(NSString *)pImagePath
text:(NSString *)pText {
if (! (self = [super init])) {
NSLog(@"*Error* MyData initWithImagePathString");
return
self;
}// end if
self.nsStrText = pText;
self.nsImageObj
= [[NSImage alloc] initWithContentsOfFile:pImagePath];
return
self;
}// end initWithImagePathString
@end
Bindings
Control as NSTableView Data Source and Delegate plus connections to buttons
NSTableView Connections: make control the Data Source and Delegate
Location of image files relative to the xcode source code
Example source code
Download 070-NSTableView-ImageAndTextCell.zip (7.5 MB)相关文章推荐
- [Cocoa]TextField delegate and notification
- 通过RTLabel、RCLabel、FTCoreText及webView结合SDWebImage等4种方式实现左滑或下拉中cell中图文混排使用场景方案
- 通过RTLabel、RCLabel、FTCoreText及webView结合SDWebImage等4种方式实现左滑或下拉中cell中图文混排使用场景方案
- iOS开发tableView的cell里面有textField,键盘出现的时候,自动上移
- 通过RTLabel、RCLabel、FTCoreText及webView结合SDWebImage等4种方式实现左滑或下拉中cell中图文混排使用场景方案
- NSTableView and NSTextFiled
- Table View Cell中有TextField,实现界面随键盘上升
- Customerize NSTableHeaderCell and apply it in tableview
- 通过RTLabel、RCLabel、FTCoreText及webView结合SDWebImage等4种方式实现左滑或下拉中cell中图文混排使用场景方案
- 在tableView中监听cell上textField的点击和键盘通知
- TableView的Cell中有Textfield、TextView时放置键盘遮挡输入框
- TextView and EditView show image
- TableView cell section TextField ALert
- [ios]TableView的Cell中有Textfield时放置键盘遮挡输入框
- 自定义属性之LinearLayout ImageView TextView模拟图片文字按钮
- 固定cell.imageView.image的大小
- android imageView 和TextVIew 颜色的透明度问题
- 自定义可点击的ImageSpan并在TextView中内置“View“
- 关于textView,textField及delegate的应用
- UITableView延伸:点击cell关闭键盘,加载不同cell,监听里面的textfeild内容改变