UIView drawRect是不平滑的,即不能平滑地在屏幕上滾動。我曾嘗試以不同的時間間隔從200毫秒到500毫秒執行'setNeedsDisplay',並且似乎沒有任何內容可以改進外觀。那是因爲地塊在屏幕上移動並停止並開始。 有沒有什麼辦法可以改善這一點,讓顯示更流暢?UIView drawRect是生澀的
/*==============================================================================*/
/* 'drawRect' - override function. */
/* */
/* This function is responsible for plotting cardiac waveforms (ECG) and also */
/* erases any prior ECG plot values that may be currently visible on the */
/* screen. */
/* */
/* It does this indirectly via 'EcgThread' or 'ECGErase' which send the */
/* 'setNeedsDisplay' message which triggers the 'drawRect' callback function. */
/* Once an ECG is started 'EcgThread' controls the frequency of 'drawRect' */
/* being by simple timer. (See 'EcgThread' for current timer value.) */
/* */
/*==============================================================================*/
/* Here's how the entire ECG process works: */
/* */
/* 1) User starts ECG which causes a 'send_ecg' command to be sent to */
/* 'CommThread'. */
/* */
/* 2) 'CommThread' the sends the 'send_ecg' command to the Pacemaker and then */
/* sends itself the 'read_ecg' command.*/
/* */
/* 3) The Pacemaker then starts acquiring 64 cardiac A/D samples (10-bits) per */
/* second and sends them back to 'CommThread'. */
/* */
/* 4) As samples are received by 'CommThread' (via 'read_ecg') on a streaming */
/* basis they are stored in 'ECGY' array (vertical plots) in reverse order */
/* i.e., from top to bottom (currently room for 128 samples). */
/* */
/* 5) 'EcgThread' runs continuously on a timer basis sending 'setNeedsDisplay' */
/* message which causes 'iOS' to perform callbacks to 'drawRect' who is */
/* responsible for drawing the cardiac (plots) waveforms from left to right */
/* across (horizontally) the screen. */
/* */
/* 6) 'drawRect' processes 'ECGY' bottom to top (opposite of 'CommThread') and */
/* each draw loop (plotting new values) takes about 13-millseconds. This is */
/* necessary because not doing so results in drawing upside down plots. */
/* */
/* 7) User stops ECG and 'TimerProc' sends a series of 'send_ecgstop' commands */
/* to 'CommThread' who in turn sends the 'send_ecgstop' commands to the PM. */
/* The reason why we send multiple 'send_ecgstop' is due to the streaming */
/* nature of the sending ECG samples and getting the PM to 'listen' to us. */
/* Usually stopping will go smoothly. Occasionally it may be necessary to */
/* move the Wand away, wait a few seconds and place Wand back over patient's */
/* chest (causing an interrupt) before normal operation returns. */
/* */
/*==============================================================================*/
- (void) drawRect : (CGRect) rect // Callback routine
{
int i, ii, x, xx, y; // Local array indices
fEcgDraw = YES; // Show 'drawRect' is running
[super drawRect : rect]; // Call standard handler
CGContextRef context = UIGraphicsGetCurrentContext(); // Get graphics context
CGContextSetAllowsAntialiasing (context, NO); // Turn off anti-alliaing
CGContextSetLineWidth (context, 1); // Set width of 'pen'
/*==============================================================================*/
/* 'HH' is used as a height bias in order to position the waveform plots in */
/* middle of the view (screen). */
/*==============================================================================*/
HH = 424; // Force height bias for now
if (fEcgErase == YES) // Show we erase the view?
{
CGContextSetStrokeColorWithColor (context, // Set color of 'pen'
[UIColor blackColor].CGColor); // Black (to erase)
/*==============================================================================*/
/* Erase the last screen. */
/*==============================================================================*/
for (i = 0, x = 0; i < 127; i++) // Iterate for all array elements
{
CGContextMoveToPoint (context, // Update current position to specified point
ECGX[x], // Starting X-coordinate
(HH - ECGS[x])); // Starting Y-coordinate (with height bias)
CGContextAddLineToPoint (context, ECGX[(x + 1)], // Draw line from current position
(HH - ECGS[((x + 1) % 127)])); // Ending Y-coordinate (with height bias)
x++; // Step to next array element
} // end - for (i = 0; i < 127; i++)
CGContextClosePath (context); // Close current path
CGContextStrokePath (context); // Stroke current path (paint the path)
fEcgErase = NO; // Reset erase flag
} // end - if (fEcgErase == YES)
else if (fECGLOOP) // Did request come from 'EcgThread'?
/*==============================================================================*/
/* Draw ECG cardiac waveforms on view. */
/*==============================================================================*/
{
xx = 1; // Counts markers
x = 0; // Reset horizontal axis
y = YY; // Use saved startimg ECGY[] index
ii = 0; // Initialize marker count
#define GRIDSIZE 12 // Grid width in pixels
int width = rect.size.width; // Get the view width
int height = rect.size.height; // Get the view height
/*==============================================================================*/
/* First draw a grid pattern to draw ECG waveforms into. */
/*==============================================================================*/
CGContextSetStrokeColorWithColor (context, // Set color of 'pen'
[UIColor lightGrayColor].CGColor); // Use 'light gray' for grid pattern
for (i = 0; i <= width; i = i+GRIDSIZE) // First the vertical lines
{
CGContextMoveToPoint (context, i, 0); // Update current position to specified point
CGContextAddLineToPoint (context, i, height); // Draw line from current position
} // end - for (i = 0; i <= width; i = i+GRIDSIZE)
for (i = 0 ; i <= height; i = i+GRIDSIZE) // Then the horizontal lines
{
CGContextMoveToPoint (context, 0, i); // Update current position to specified point
CGContextAddLineToPoint (context, width, i); // Draw line from current position
} // end - for (i = 0 ; i <= height; i = i+GRIDSIZE)
CGContextClosePath (context); // Close current path
CGContextStrokePath (context); // Stroke current path (paint the path)
/*==============================================================================*/
/* Now draw (plot) cardiac waveforms using using pre-stored ECG sample values. */
/*==============================================================================*/
for (i = 0; i < 127; i++) // Iterate for number ECGY[] entries
{
/*==============================================================================*/
/* Erase the prior ECG A/D plot value. */
/*==============================================================================*/
#if 0 // NOT NEEDED CUZ WE SELECTED CLEAR CONTEXT IN EcgViewController.xib
CGContextSetStrokeColorWithColor (context, // Set color of 'pen'
[UIColor blackColor].CGColor); // Black to erase old plot
CGContextMoveToPoint (context, // Update current position to specified point
ECGX[x], // Starting X-coordinate of prior position
(HH - ECGS[x])); // Starting Y-corrdinate with height bias
CGContextAddLineToPoint (context, // Draw line from current position
ECGX[(x + 1)], // Ending X-coordinate
(HH - ECGS[((x + 1))])); // Ending Y-coordinate using saved Y-axis (with height bias)
CGContextClosePath (context); // Close current path
CGContextStrokePath (context); // Stroke current path (paint the path)
#endif // NOT NEEDED CUZ WE SELECTED CLEAR CONTEXT IN EcgViewController.xib
/*==============================================================================*/
/* Plot the next ECG A/D plot value. */
/*==============================================================================*/
CGContextSetStrokeColorWithColor (context, // Set color of 'pen'
[UIColor greenColor].CGColor); // White to draw new plot
CGContextMoveToPoint (context, // Update current position to specified point
ECGX[x], // Starting X-coordinate of new position
(HH - ECGY[y])); // Starting Y-coordinate with height bias
CGContextAddLineToPoint (context, // Draw line & prevent overrun
ECGX[(x + 1)], // Ending X-coordinate
(HH - ECGY[((y + 1) % 127)])); // Ending Y-axis (with height bias)
CGContextClosePath (context); // Close current path
CGContextStrokePath (context); // Stroke current path (paint the path)
ECGS[x] = ECGY[y]; // Save last plot value for erase
x++; // Next ECGX[] (y-axis) plot value index
/*==============================================================================*/
/* Below as we increment 'y' it will eventually roll to zero and when we get */
/* to the end of the above 'for' loop 'y' will have its starting value. */
/*==============================================================================*/
y = ((y + 1) % 127); // Next ECGY[] (y-axis) plot value & prevent overrun
ulPlots++; // Count number of plots
} // end - for (i = 0; i < 127; i++)
y = ((y + 16) % 127); // Next starting y-axis 'ECGY' index
YY = y; // Save it for next iteration
EcgCount = 0; // Reset skip count (inc. by 'CommThread'
} // end - if (fEcgErase == YES)
// UIGraphicsPopContext();
fEcgDraw = NO; // Show 'drawRect' not running
// [NSThread sleepForTimeInterval : 0.1]; // Delay a little
} // end - 'drawRect'
/*===============================END OF FUNCTION================================*/
不要只是粘貼一堆代碼,並詢問如何提高性能。首先解釋代碼試圖做什麼,然後解釋你所嘗試過的。你做了什麼測量?他們告訴你什麼? –