0
我有一個窗口包含NSTableView的可可應用程序。每行有幾列,三個收音機和兩個按鈕。目前該表格有260行,當窗口被關注時,表格視圖中的滾動非常緩慢和緊張。當窗口未聚焦時,我將鼠標懸停在桌面視圖上並滾動它的滑動順暢。可可應用程序在窗口焦點上滾動速度慢,不快時不快
我試圖通過更改背景圖和啓用CoreAnimation圖層無濟於事解決緩慢的性能。
爲什麼當窗口沒有對焦時滾動速度會很快,但是當它變慢時,滾動會很快?
我只是很困惑,爲什麼滾動是如此緩慢。
這裏是我的ProposalTableViewController.h
#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>
#import <QuickLook/QuickLook.h>
#import <Quartz/Quartz.h>
@interface ProposalTableViewController : NSObject<NSTableViewDataSource, NSTableViewDelegate, QLPreviewPanelDelegate, QLPreviewPanelDataSource>{
@public
NSMutableArray *list;
IBOutlet NSTableView *tableView;
IBOutlet NSSearchField *searchText;
IBOutlet NSTextField *countTextField;
}
@property (strong) QLPreviewPanel *previewPanel;
+ (ProposalTableViewController *)getInstance;
- (IBAction)deleteRow:(id)sender;
- (IBAction)exportData:(id)sender;
- (void)loadData;
- (void)countItems;
@end
而且我ProposalTableViewController.m
#import "ProposalTableViewController.h"
#import "Proposal.h"
#import "StatusRadioView.h"
#import "DBManager.h"
#import "filePathButtonView.h"
#import <Quartz/Quartz.h>
#import "AppDelegate.h"
@implementation Proposal (QLPreviewItem)
- (NSURL *)previewItemURL
{
return [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@.pdf",self.filePath]];
}
- (NSString *)previewItemTitle
{
return [NSString stringWithFormat:@"Proposal %@",self.proposalNumber];
}
@end
@implementation ProposalTableViewController
static ProposalTableViewController *instance;
+ (ProposalTableViewController *)getInstance{
return instance;
}
//------------------------------------------------------------------------------------------------------------------------------------
// Init
//------------------------------------------------------------------------------------------------------------------------------------
- (id)init{
self = [super init];
if(self){
instance = self;
list = [[NSMutableArray alloc] init];
[self loadData];
for (NSTableColumn *tableColumn in tableView.tableColumns) {
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:tableColumn.identifier ascending:YES selector:@selector(compare:)];
[tableColumn setSortDescriptorPrototype:sortDescriptor];
}
}
return self;
}
//------------------------------------------------------------------------------------------------------------------------------------
// Load Data from SQLite
//------------------------------------------------------------------------------------------------------------------------------------
- (void)loadData {
list = [[DBManager getProposalTable] select:@""];
NSSortDescriptor* desc = [[NSSortDescriptor alloc] initWithKey:@"proposalNumber" ascending:NO selector:@selector(compare:)];
[list sortUsingDescriptors:[NSArray arrayWithObjects:desc, nil]];
[tableView reloadData];
[self countItems: list];
}
//------------------------------------------------------------------------------------------------------------------------------------
// Number of Rows in Table View
//------------------------------------------------------------------------------------------------------------------------------------
- (NSInteger) numberOfRowsInTableView:(NSTableView *)tableView {
return [list count];
}
-(void)countItems:(NSArray *)list; {
NSString *countText;
int size = [list count];
if (size == 1){
countText = @"item in list";
}else{
countText = @"items in list";
}
NSString *itemCount = [NSString stringWithFormat:@"%d %@", size, countText];
[countTextField setStringValue:itemCount];
}
//------------------------------------------------------------------------------------------------------------------------------------
// Get View for Table Column
//------------------------------------------------------------------------------------------------------------------------------------
- (NSView *)tableView:(NSTableView *)table_view viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
Proposal *p = [list objectAtIndex:row];
NSString *identifier = [tableColumn identifier];
NSString *holdingValue;
NSTableCellView *cell = [table_view makeViewWithIdentifier:identifier owner:self];
if([identifier isEqualToString:@"status"]){
StatusRadioView *radioView = [[StatusRadioView alloc] initWithProposal:p];
return radioView;
}else if ([identifier isEqualToString:@"filePath"]){
filePathButtonView *buttonView = [[filePathButtonView alloc]initWithProposal:p];
return buttonView;
}else if ([identifier isEqualToString:@"clientAccessPoint"]){
holdingValue = [p valueForKey:identifier];
if (!holdingValue){
cell.textField.stringValue = @"N/A";
}else{
cell.textField.stringValue = [p valueForKey:identifier];
}
}else{
cell.textField.stringValue = [p valueForKey:identifier];
}
return cell;
}
//------------------------------------------------------------------------------------------------------------------------------------
// Sort Descriptors did Change
//------------------------------------------------------------------------------------------------------------------------------------
-(void)tableView:(NSTableView *)mtableView sortDescriptorsDidChange:(NSArray *)oldDescriptors {
[list sortUsingDescriptors: [mtableView sortDescriptors]];
[tableView reloadData];
}
//table row height
-(CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row {
return 25;
}
//------------------------------------------------------------------------------------------------------------------------------------
// Search Text did Change
//------------------------------------------------------------------------------------------------------------------------------------
- (void)controlTextDidChange:(NSNotification *)notification {
NSSortDescriptor* desc = [[NSSortDescriptor alloc] initWithKey:@"proposalNumber" ascending:NO selector:@selector(compare:)];
NSTextField *textField = [notification object];
NSString *str = [textField stringValue];
list = [[DBManager getProposalTable] select:str];
[list sortUsingDescriptors:[NSArray arrayWithObjects:desc, nil]];
[tableView reloadData];
[self countItems: list];
}
//------------------------------------------------------------------------------------------------------------------------------------
// Export DATA
//------------------------------------------------------------------------------------------------------------------------------------
- (IBAction)exportData:(id)sender{
NSString *content = @"";
for(Proposal *p in list){
NSString *row = [NSString stringWithFormat:@"%@,%@,%@,%@,%@,%@,%@,%@,%@,%@", p.proposalNumber,p.itemNumber,p.clientName,p.medium,p.support,p.cost,p.dateCreated,p.status,p.dateStatusChanged,p.clientAccessPoint];
row = [row stringByReplacingOccurrencesOfString:@"\n" withString:@""];
row = [NSString stringWithFormat:@"%@\n", row];
content = [content stringByAppendingString:row];
}
//get the documents directory:
NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Baumgartner Fine Art Restoration"];
NSString *fileName = [documentsDirectory stringByAppendingPathComponent:@"proposalBuilderDatabase.csv"];
[[NSFileManager defaultManager] createDirectoryAtPath:documentsDirectory
withIntermediateDirectories:NO
attributes:nil
error:nil];
[content writeToFile:fileName
atomically:NO
encoding:NSStringEncodingConversionAllowLossy
error:nil];
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:@"Export Succeeded"];
[alert addButtonWithTitle:@"Ok"];
[alert runModal];
}
//------------------------------------------------------------------------------------------------------------------------------------
// Delete row from DB and table
//------------------------------------------------------------------------------------------------------------------------------------
- (IBAction)deleteRow:(id)sender{
NSString *row = list[tableView.selectedRow];
NSString *mid = [row valueForKey:@"m_id"];
ProposalTable *deleteRow = [[ProposalTable alloc] init];
[deleteRow deleteWithId: mid];
[self loadData];
[tableView reloadData];
}
//------------------------------------------------------------------------------------------------------------------------------------
// QuickLook
//------------------------------------------------------------------------------------------------------------------------------------
- (NSInteger)numberOfPreviewItemsInPreviewPanel:(QLPreviewPanel *)panel {
return [list count];
}
- (id <QLPreviewItem>)previewPanel:(QLPreviewPanel *)panel previewItemAtIndex:(NSInteger)index {
return list[tableView.selectedRow];
}
- (BOOL)previewPanel:(QLPreviewPanel *)panel handleEvent:(NSEvent *)event {
// redirect all key down events to the table view
if ([event type] == NSKeyDown) {
[tableView keyDown:event];
return YES;
}
return NO;
}
// This delegate method provides the rect on screen from which the panel will zoom.
- (NSRect)previewPanel:(QLPreviewPanel *)panel sourceFrameOnScreenForPreviewItem:(id <QLPreviewItem>)item {
return NSZeroRect;
}
- (BOOL)tableView:(NSTableView *)tableView shouldSelectRow:(NSInteger)rowIndex {
[[QLPreviewPanel sharedPreviewPanel]reloadData];
return YES;
}
@end
這裏是我的ProposalTableView.h
#import <Cocoa/Cocoa.h>
@interface ProposalTableView : NSTableView
@end
而且我ProposalTableView.m
#import "ProposalTableView.h"
#import "AppDelegate.h"
@implementation ProposalTableView
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
self.wantsLayer = YES;
// Drawing code here.
}
- (void)keyDown:(NSEvent *)theEvent
{
NSString *key = [theEvent charactersIgnoringModifiers];
if ([key isEqual:@" "])
{
[[NSApp delegate] togglePreviewPanel:self];
}
else
{
[super keyDown:theEvent];
}
}
@end
還有一些代碼可以建立SqLite數據庫連接並與數據庫進行交互以獲取記錄或刪除等......但這裏並不是真的需要......我也有代碼來繪製單選按鈕和其他按鈕但是,我不認爲這是必要的,除非有人認爲該圖正在造成經濟放緩......?
你能告訴我們一些代碼嗎?你使用'NSScrollViewDelegate'方法嗎?請提供您的控制器代碼。 – Astoria
@Astoria'NSScrollView'沒有委託。 – Willeke
@Willeke你是對的,事實並非如此。我的意思是'NSViewBoundsDidChangeNotification'通知的回調方法。 – Astoria